Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get the current scroll position of a SwiftUI ScrollView

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!

like image 963
Mofawaw Avatar asked Jun 26 '20 04:06

Mofawaw


People also ask

What is Contentoffset?

The point at which the origin of the content view is offset from the origin of the scroll view.

What is scrollEventThrottle?

scrollEventThrottle: It is used to control the firing of scroll events while scrolling.

What is Lazyvstack?

A view that arranges its children in a line that grows vertically, creating items only as needed.

Is there a ScrollView equivalent in SwiftUI?

We will explore a ScrollView, UIScrollView equivalent in SwiftUI. List view is a view that contains child views and displays them in a scrollable manner. SwiftUI offers two views with this capability, ScrollView and List. In the previous post, we learned two ways to populate a list view's content.

How does ScrollView work?

The scroll view displays its content within the scrollable content region. As the user performs platform-appropriate scroll gestures, the scroll view adjusts what portion of the underlying content is visible. ScrollView can scroll horizontally, vertically, or both, but does not provide zooming functionality.

How to make a scroll view scroll horizontally in jQuery?

By default, the scroll view will create with a vertical scrolling direction. To make a scroll view scroll horizontally, you passing Axis.Set.horizontal as axes argument. <1> Set axes as .horizontal to enable horizontal scrolling. <2> We use HStack instead of VStack here to align our child views horizontally.

What is a scrollable view in Salesforce?

A scrollable view. The scroll view displays its content within the scrollable content region. As the user performs platform-appropriate scroll gestures, the scroll view adjusts what portion of the underlying content is visible. ScrollView can scroll horizontally, vertically, or both, but does not provide zooming functionality.


2 Answers

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()
    }
}
like image 191
Asperi Avatar answered Oct 08 '22 01:10

Asperi


I found a version without using PreferenceKey. The idea is simple - by returning Color from GeometryReader, we can set scrollOffset directly inside background modifier.

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 { proxy -> Color in
                DispatchQueue.main.async {
                    offset = -proxy.frame(in: .named("scroll")).origin.y
                }
                return Color.clear
            })
        }.coordinateSpace(name: "scroll")
    }
}
like image 7
Mofawaw Avatar answered Oct 08 '22 03:10

Mofawaw