Skip to content

Instantly share code, notes, and snippets.

@Kievkao
Created September 9, 2020 07:09
Show Gist options
  • Save Kievkao/0682dc8814a953640ca9b74413424bb8 to your computer and use it in GitHub Desktop.
Save Kievkao/0682dc8814a953640ca9b74413424bb8 to your computer and use it in GitHub Desktop.
How to get ScrollView offset in SwiftUI
struct ContentView: View {
var body: some View {
ScrollViewOffset(onOffsetChange: { (offset) in
print("New ScrollView offset: \(offset)")
}) {
VStack {
ForEach(0..<100) { index in
Text("\(index)")
}
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct ScrollViewOffset<Content: View>: View {
let onOffsetChange: (CGFloat) -> Void
let content: () -> Content
init(
onOffsetChange: @escaping (CGFloat) -> Void,
@ViewBuilder content: @escaping () -> Content
) {
self.onOffsetChange = onOffsetChange
self.content = content
}
var body: some View {
ScrollView {
offsetReader
content()
.padding(.top, -8)
}
.coordinateSpace(name: "frameLayer")
.onPreferenceChange(OffsetPreferenceKey.self, perform: onOffsetChange)
}
var offsetReader: some View {
GeometryReader { proxy in
Color.clear
.preference(
key: OffsetPreferenceKey.self,
value: proxy.frame(in: .named("frameLayer")).minY
)
}
.frame(height: 0)
}
}
private struct OffsetPreferenceKey: PreferenceKey {
static var defaultValue: CGFloat = .zero
static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment