Skip to content

Instantly share code, notes, and snippets.

@michaelevensen
Last active September 12, 2022 12:42
Show Gist options
  • Save michaelevensen/b2617606b3c6bcad7b9a4789d9441150 to your computer and use it in GitHub Desktop.
Save michaelevensen/b2617606b3c6bcad7b9a4789d9441150 to your computer and use it in GitHub Desktop.
Allows you to track `ScrollView` offset in SwiftUI. From https://swiftwithmajid.com/2020/09/24/mastering-scrollview-in-swiftui/
private struct ScrollOffsetPreferenceKey: PreferenceKey {
static var defaultValue: CGPoint = .zero
static func reduce(value: inout CGPoint, nextValue: () -> CGPoint) {}
}
struct TrackableScrollView<Content: View>: View {
let axes: Axis.Set
let showsIndicators: Bool
let offsetChanged: (CGPoint) -> Void
let content: Content
init(
axes: Axis.Set = .vertical,
showsIndicators: Bool = true,
offsetChanged: @escaping (CGPoint) -> Void = { _ in },
@ViewBuilder content: () -> Content
) {
self.axes = axes
self.showsIndicators = showsIndicators
self.offsetChanged = offsetChanged
self.content = content()
}
var body: some View {
SwiftUI.ScrollView(axes, showsIndicators: showsIndicators) {
GeometryReader { geometry in
Color.clear.preference(
key: ScrollOffsetPreferenceKey.self,
value: geometry.frame(in: .named("scrollView")).origin
)
}.frame(width: 0, height: 0)
content
}
.coordinateSpace(name: "scrollView")
.onPreferenceChange(ScrollOffsetPreferenceKey.self, perform: offsetChanged)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment