I have a search bar on top of the screen. I need to hide when scrolling down and unhide when scrolling up, which I achieved using this answer.
But I found one issue with the calculation of wholeSize and scrollViewSize. It is giving different values on different scrolls. Suppose I am scrolling down and I am at position y = 400 from origin, scrollViewSize = 740. Now again when I come back scrolling at this same position, y = 400, scrollViewSize = 789. The number is not exact, only for the inference.
I have already explored the answer above; the issue I'm facing is that sometimes, while on the bottom of the screen, the statement currentOffset >= scrollViewSize.height - wholeSize.height becomes false. My ScrollView bounces when it is on the bottom of the screen which I needed to be there. Here is a partial code snippet:
.background(GeometryReader {
Color.clear.preference(key: ViewOffsetKey.self, value: -$0.frame(in: .named("scroll")).origin.y)
}).onPreferenceChange(ViewOffsetKey.self) { currentOffset in
let offsetDifference: CGFloat = self.previousScrollOffset - currentOffset
if ( abs(offsetDifference) > minimumOffset) {
if currentOffset >= scrollViewSize.height - wholeSize.height {
Utilities.DBLog(_object: "currentOffset \(currentOffset)")
Utilities.DBLog(_object: "wholeSize.height \(wholeSize.height)")
Utilities.DBLog(_object: "scrollViewSize.height \(scrollViewSize.height)")
Utilities.DBLog(_object: "User has reached the bottom of the ScrollView.")
DispatchQueue.main.async {
withAnimation(.easeOut(duration: ZIAnimation.durationPoint6)) {
if show ?? false {
show = false
}
}
}
}
else
if offsetDifference > 0 || self.previousScrollOffset < 0 {
Utilities.DBLog(_object: "Is scrolling up toward top.")
Utilities.DBLog(_object: self.previousScrollOffset)
Utilities.DBLog(_object: "currentOffset \(currentOffset)")
Utilities.DBLog(_object: offsetDifference)
Utilities.DBLog(_object: "wholeSize.height \(wholeSize.height)")
Utilities.DBLog(_object: "scrollViewSize.height \(scrollViewSize.height)")
DispatchQueue.main.async {
withAnimation(.easeOut(duration: ZIAnimation.durationPoint3)) {
if !(show ?? false) {
show = true
}
}
}
} else if offsetDifference < 0 {
Utilities.DBLog(_object: "Is scrolling down toward bottom.")
Utilities.DBLog(_object: self.previousScrollOffset)
Utilities.DBLog(_object: "currentOffset \(currentOffset)")
Utilities.DBLog(_object: offsetDifference)
Utilities.DBLog(_object: "wholeSize.height \(wholeSize.height)")
Utilities.DBLog(_object: "scrollViewSize.height \(scrollViewSize.height)")
DispatchQueue.main.async {
withAnimation(.easeOut(duration: ZIAnimation.durationPoint6)) {
if show ?? false {
show = false
}
}
}
}
self.previousScrollOffset = currentOffset
}
}