Get the current scroll position of a SwiftUI ScrollView

ghz 1years ago ⋅ 8201 views

Question

With the new ScrollViewReader, it seems possible to set the scroll offset programmatically.

But I was wondering if it is also possible to get the current scroll position?

It seems like the ScrollViewProxy only comes with the scrollTo method, allowing us to set the offset.

Thanks!


Answer

It was possible to read it and before. Here is a solution based on view preferences.

struct DemoScrollViewOffsetView: View {
    @State private var offset = CGFloat.zero
    var body: some View {
        ScrollView {
            VStack {
                ForEach(0..<100) { i in
                    Text("Item \(i)").padding()
                }
            }.background(GeometryReader {
                Color.clear.preference(key: ViewOffsetKey.self,
                    value: -$0.frame(in: .named("scroll")).origin.y)
            })
            .onPreferenceChange(ViewOffsetKey.self) { print("offset >> \($0)") }
        }.coordinateSpace(name: "scroll")
    }
}

struct ViewOffsetKey: PreferenceKey {
    typealias Value = CGFloat
    static var defaultValue = CGFloat.zero
    static func reduce(value: inout Value, nextValue: () -> Value) {
        value += nextValue()
    }
}

[backup](https://github.com/Asperi- Demo/4SwiftUI/blob/master/Answers/Get_current_scroll_position_SwiftUI.md)