Middle+
What is PreferenceKey in the context of iOS development?
sobes.tech AI
Answer from AI
PreferenceKey is a protocol in SwiftUI that allows passing values from child views up the view hierarchy. It is used to gather information about sizes, positions, or other characteristics of child views, which can be used in parent views for layout or behavior decisions.
Main components:
- Key: A type that conforms to the
PreferenceKeyprotocol. It defines the type of value to be passed and how to combine multiple values (reducemethod).struct MySizePreferenceKey: PreferenceKey { static var defaultValue: CGSize = .zero // Default value static func reduce(value: inout CGSize, nextValue: () -> CGSize) { // Logic to combine values. // For example, choose the maximum size or sum them. // Example: value = max(value, nextValue()) // Example for summing: value.width += nextValue().width; value.height += nextValue().height value = nextValue() // Just take the last value (for example) } } - Setting the value: Child view sets the value using the
.preference(key:value:)modifier.Text("Hello") .background(GeometryReader { geometry in Color.clear.preference(key: MySizePreferenceKey.self, value: geometry.size) }) - Reading the value: Parent view reads the collected value using the
.onPreferenceChangemodifier.VStack { // Child views setting preferences Text("Example 1") .background(GeometryReader { geometry in Color.clear.preference(key: MySizePreferenceKey.self, value: geometry.size) }) Text("Long example") .background(GeometryReader { geometry in Color.clear.preference(key: MySizePreferenceKey.self, value: geometry.size) }) } .onPreferenceChange(MySizePreferenceKey.self) { size in // You can use the aggregated size here print("Aggregated size:", size) }
When to use:
- To get sizes of child elements for adaptive parent layout.
- To pass information about element positions.
- To create custom anchors.
- To collect state or properties from multiple child views.
Difference from Environment:
Environmentpasses data down the view hierarchy.PreferenceKeypasses data up the view hierarchy and allows collecting/merging values from multiple child elements.