Go to file
Casper Zandbergen 82a0087388 Podspec dependency 2020-07-14 10:09:21 +02:00
Sources/ScrollViewProxy Added @available so the package can be used in backwards compatible projects 2020-06-03 17:07:13 +02:00
.gitignore initial commit 2020-06-03 10:05:52 +02:00
Package.swift Added platform restriction 2020-06-17 17:31:44 +02:00
README.md Update README.md 2020-06-23 11:15:09 +02:00
ScrollViewProxy.podspec Podspec dependency 2020-07-14 10:09:21 +02:00

README.md

As of June 22nd this is included in the SwiftUI beta. https://developer.apple.com/documentation/swiftui/scrollviewproxy

The Apple implementation uses just .id(_:) and I had update issues with that where Views with an id sometimes won't update when their ObservedObject changed. Maybe this has been fixed in the new SwiftUI beta.

Also the Apple implementation only supports iOS 14 so I think this repo is still useful.

ScrollViewProxy

Adds ScrollViewReader and ScrollViewProxy that help you scroll to locations in a ScrollView

To get a ScrollViewProxy you can either use the conveinience init on ScrollView

ScrollView { proxy in
    ...
}

or add a ScrollViewReader to any View that creates a UIScrollView under the hood

List {
    ScrollViewReader { proxy in
        ...
    }
}

The ScrollViewProxy currently has two functions you can call

/// Scrolls to an edge or corner
public func scrollTo(_ alignment: Alignment, animated: Bool = true)

/// Scrolls the view with ID to an edge or corner
public func scrollTo(_ id: ID, alignment: Alignment = .top, animated: Bool = true)

To use the scroll to ID function you have to add a view with that ID to the ScrollViewProxy

ScrollView { proxy in
    HStack { ... }
        .id("someId", scrollView: proxy)
}

Example

Everything put together in an example

struct ScrollViewProxySimpleExample: View {
    
    @State var randomInt = Int.random(in: 0..<200)
    @State var proxy: ScrollViewProxy<Int>? = nil
    
    var body: some View {
        VStack {
            ScrollView { proxy in
                ForEach(0..<200) { index in
                    VStack {
                        Text("\(index)").font(.title)
                        Spacer()
                    }
                    .padding()
                    .id(index, scrollView: proxy)
                }.onAppear {
                    self.proxy = proxy
                }
            }
            HStack {
                Button(action: {
                    self.proxy?.scrollTo(self.randomInt, alignment: .center)
                    self.randomInt = Int.random(in: 0..<200)
                }, label: {
                    Text("Go to \(self.randomInt)")
                })
                Spacer()
                Button(action: { self.proxy?.scrollTo(.top) }, label: {
                    Text("Top")
                })
                Spacer()
                Button(action: { self.proxy?.scrollTo(.center) }, label: {
                    Text("Center")
                })
                Spacer()
                Button(action: { self.proxy?.scrollTo(.bottom) }, label: {
                Text("Bottom")
                })
            }
        }
    }
}