Middle+
What is PreferenceKey in the context of SwiftUI?
sobes.tech AI
Answer from AI
PreferenceKey is a protocol in SwiftUI that allows passing values "up" the view tree. It is used to gather information from child views and deliver it to parent views, which can then use this information to modify their behavior or appearance.
Key features of PreferenceKey:
- Protocol: Implement the
PreferenceKeyprotocol, defining the value type and a method for combining values. associatedtype Value: Defines the data type to be passed.static func reduce(value: inout Value, nextValue: () -> Value): Called by SwiftUI to combine values from multiple child views. You define how to merge the current value (value) with the new one (nextValue()).- Passing values: Child views use the
.preference(key:value:)modifier to set a value for a specificPreferenceKey. - Reading values: Parent views use
.onPreferenceChange(_:perform:)to get notified of changes to the value for a specificPreferenceKey.
Example:
Creating a PreferenceKey to determine the height of a child view:
struct ChildHeightPreferenceKey: PreferenceKey {
typealias Value = Double?
static var defaultValue: Double? = nil
static func reduce(value: inout Double?, nextValue: () -> Double?) {
value = nextValue() ?? value
}
}
Using in a view:
struct ParentView: View {
@State private var childHeight: Double? = nil
var body: some View {
VStack {
Text("Child height: \(childHeight != nil ? "\(childHeight!)" : "-")")
ChildView()
.onPreferenceChange(ChildHeightPreferenceKey.self) { newValue in
self.childHeight = newValue
}
}
}
}
struct ChildView: View {
var body: some View {
GeometryReader { geometry in
Rectangle()
.fill(Color.blue)
.frame(height: 100)
.preference(key: ChildHeightPreferenceKey.self, value: geometry.size.height)
}
.frame(height: 100)
}
}