I have a SwiftUI view with a ScrollView constructed like this:
ZStack(alignment: .top) {
Color.black
VStack {
HeaderView()
ScrollView(.vertical) {
content
}
}
}
I want to hide the HeaderView() as soon as the user scrolls down on the ScrollView, but then show it when the user scrolls back up (preferably with a bit of an offset), even if the ScrollView isn't scrolled all the way to the top.
This is done on a lot of apps, including Artifact, which does it like this:
Using GeometryReader/ScrollViewReader did not help, or I did not implement it correctly?

If you place a
GeometryReaderin the background of the scrolled content then it can be used to detect a change in scroll position. An.onChangehandler can then be used to toggle the visibility of the header when the direction of scroll changes.However, when the content is fully scrolled to the top or to the bottom, the
ScrollViewmay bounce and this may cause the header to be toggled incorrectly. To help resolve this, anotherGeometryReadercan be used to measure the height of theScrollView. The measurement of the position can then be constrained to the exact height of the content, allowing bounces to be ignored.Here is an adaption of your example to show it working:
EDIT In the OP you said you would prefer it if the header only re-appears after the content has been scrolled a little in the opposite direction. To implement this, it is necessary to detect the turning point and then measure the distance from this point. This requires the following changes to the code above:
To use the same effect for hiding the header too, change the second if-statement to: