PreferenceKey
definition
struct ScrollPrefKey: PreferenceKey {
static var defaultValue: CGFloat = 0
static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
value = nextValue()
}
}
Main Code
ScrollView {
GeometryReader { proxy in
Text("\(proxy.frame(in: .named("scroll")).minY)") // I can see changes
Color.clear.preference(key: ScrollPrefKey.self, value: proxy.frame(in: .named("scroll")).minY)
} //MARK: END GeometryReader
VStack {
//main content
Button(action: {}, label: {Text("myButton")})
}
}
.coordinateSpace(name: "scroll")
.onPreferenceChange(ScrollPrefKey.self, perform: { value in
print(value)
//DO SOME THINGS - but it never trigger
})
GeometryReader
still doesn't workstatic func reduce(value: inout Self.Value, nextValue: () -> Self.Value)
Here, nextValue: () -> Self.Value
: This function allows for logic to reduce all those preferences to a single value, if multiple values are outputted by multiple different views, all using the same PreferenceKey.
When the view loads first time, the preference key will be updated from defaultValue
to initial value. And since we have only one view producing the value with one preference key, the nextValue()
returns nil in this case.
value: inout Self.Value
:
Though the value
, which is keep accumulating through previous calls and keeps updating with the preference key value changes. So we should use the value
here.
Update the PreferenceKey
definition in the code with this:
struct ScrollPrefKey: PreferenceKey {
static var defaultValue: CGFloat? = nil
static func reduce(value: inout CGFloat?, nextValue: () -> CGFloat?) {
value = value ?? nextValue()
}
}