The ScrollViewReader
in SwiftUI is a powerful tool that allows you to programmatically control the position of a ScrollView
. It enables smooth navigation to specific views within a scrollable list by providing access to a ScrollViewProxy
, which you can use to scroll to a particular item or location. This is especially useful in applications that require dynamic, user-controlled navigation, such as chat apps, long lists, or photo galleries.
Getting Started
To use ScrollViewReader
, wrap your ScrollView
content inside a ScrollViewReader
view. The ScrollViewReader
will then provide a ScrollViewProxy
that you can use to scroll to specific items identified by unique IDs.
Here’s a basic example:
import SwiftUI
struct ContentView: View {
var body: some View {
ScrollViewReader { proxy in
ScrollView {
VStack(spacing: 6) {
ForEach(0..<50, id: \.self) { i in
Text("Item \(i)")
.frame(maxWidth: .infinity)
.padding()
.background(Color.blue.opacity(0.1))
.id(i) // Setting unique IDs
}
}
.padding()
}
.onAppear {
proxy.scrollTo(25, anchor: .center) // Scrolls to Item 25 when the view appears
}
}
}
}
#Preview {
ContentView()
}
In this example, we use ScrollViewReader
to wrap a ScrollView
containing a list of items. Each item has an ID, which allows us to scroll to any specific item using .scrollTo
modifier. Here, we scroll to item 25 when the view appears.
Animated scrolling
We can animate the scroll using withAnimation
. Let's add a couple of buttons just to see the effect:
import SwiftUI
struct ContentView: View {
var body: some View {
ScrollViewReader { proxy in
HStack {
Button {
withAnimation {
proxy.scrollTo(0, anchor: .top)
}
} label: {
Text("To top")
.frame(maxWidth: .infinity)
}
Button {
withAnimation {
proxy.scrollTo(49, anchor: .bottom)
}
} label: {
Text("To bottom")
.frame(maxWidth: .infinity)
}
}
ScrollView {
VStack(spacing: 6) {
ForEach(0..<50, id: \.self) { i in
Text("Item \(i)")
.frame(maxWidth: .infinity)
.padding()
.background(Color.blue.opacity(0.1))
.id(i)
}
}
.padding()
}
}
}
}
#Preview {
ContentView()
}
Be the first to comment