I can read the scrollPosition correctly, but scrollTo() doesn't work.
iOS 17, Xcode 15.2. Code like this below(can directly copy and paste):
import SwiftUI
struct PositionTest: View {
@State private var weathers = Weather.samples
@State private var scrollPosition: Weather.ID?
@State private var isTaped: Bool = false
var body: some View {
VStack {
Text("Scroll Position: " + (scrollPosition ?? "Cupertino"))
if !isTaped {
CollapsedView(
weathers: $weathers,
scrollPosition: $scrollPosition,
isTaped: $isTaped
)
} else {
ExpandedView(
weathers: $weathers,
scrollPosition: $scrollPosition,
isTaped: $isTaped
)
}
}
.font(.title)
.fontWeight(.semibold)
.animation(.default, value: isTaped)
}
}
#Preview {
PositionTest()
}
struct CollapsedView: View {
@Binding var weathers: [Weather]
@Binding var scrollPosition: Weather.ID?
@Binding var isTaped: Bool
var body: some View {
ScrollViewReader { proxy in
ScrollView {
VStack(spacing: 20) {
ForEach(weathers) { weather in
Text(weather.name)
.frame(width: 350, height: 227)
.foregroundStyle(.white)
.background(.blue.gradient)
.cornerRadius(40)
.id(weather.id as Weather.ID?)
.onTapGesture { isTaped.toggle() }
}
}
.frame(maxWidth: .infinity)
.scrollTargetLayout()
}
.scrollIndicators(.hidden)
.scrollTargetBehavior(.viewAligned)
.scrollPosition(id: $scrollPosition, anchor: .center)
.onAppear { proxy.scrollTo(scrollPosition, anchor: .center) }
}
}
}
struct ExpandedView: View {
@Binding var weathers: [Weather]
@Binding var scrollPosition: Weather.ID?
@Binding var isTaped: Bool
var body: some View {
ScrollViewReader { proxy in
ScrollView {
VStack(spacing: 20) {
ForEach(weathers) { weather in
Text(weather.name)
.frame(width: 250, height: 227)
.foregroundStyle(.white)
.background(.indigo.gradient)
.clipShape(.circle)
.id(weather.id as Weather.ID?)
.onTapGesture { isTaped.toggle() }
}
}
.frame(maxWidth: .infinity)
.scrollTargetLayout()
}
.scrollIndicators(.hidden)
.scrollTargetBehavior(.viewAligned)
.scrollPosition(id: $scrollPosition, anchor: .center)
.onAppear { proxy.scrollTo(scrollPosition, anchor: .center) }
}
}
}
struct Weather: Identifiable {
var id: String { name }
let name: String
let temp: Int
static let samples = [
Weather(name: "Cupertino", temp: 12),
Weather(name: "New York", temp: 13),
Weather(name: "ShangHai", temp: 14),
Weather(name: "London", temp: 15),
Weather(name: "Las Vegas", temp: 16),
]
}
I found if I simply change the VStack to LazyVStack in both CollapsedView() and ExpandedView(), the scrollTo() method works fine.
But in my project, for some reason I don't want to use LazyVStack, just want to use VStack, is there any way to make scorllTo() works in VStack?