26
Oct
2020
Scrolling ScrollView programatically
Reading time: 1 min
This recipe is about how to scroll a SwiftUI ScrollView
programatically. Here's a quick breakdown of what to do:
- For iOS 13 - tough luck - it can't be done. For whatever reason, this is one of things that were deemed less important for the initial release of SwiftUI.
- For iOS 14 and above - embed your
ScrollView
's root view in aScrollViewReader
, and then use thescrollTo
method.
scrollTo
takes as a parameter the ID of the child view to scroll to. It's not a position or a Y value - you can't scroll to whichever point in the ScrollView
you'd like. Set the ID of the child view using the method id
, that's available for all SwiftUI View
s:
let range = 1..<30
var body: some View {
ScrollView {
ScrollViewReader { proxy in
ForEach(1..<30) { value in
Text("\(value)")
.id(value) // the ID can be any hashable
}
Button("Scroll to random") {
proxy.scrollTo(Int.random(in: range))
}
}
}
}
If your app needs to support iOS 13 as well, use pack the scrolling action in an optional closure, and use the #available
conditional:
let range = 1..<30
var body: some View {
ScrollView {
if #available(iOS 14.0, *) {
ScrollViewReader { proxy in
mainView {
proxy.scrollTo(Int.random(in: range))
}
}
} else {
mainView()
}
}
}
func mainView(scroll: (() -> Void)? = nil) -> some View {
Group {
ForEach(1..<30) { value in
Text("\(value)")
.id(value) // the ID can be any hashable
}
Button((scroll != nil) ? "Scroll to random" : "I'm kinda useless :(") {
scroll?()
}
}
}