我在 SwiftUI 中实现了以下清理器。+
按钮应该ScrollView
向上移动 1 个刻度(或scrollPosition
增加 1),但问题是,直到我单击 8-9 次后才会发生滚动。这是 iOS 中的错误还是编程错误?
struct BrokenVerticalScrubberDemo: View {
@State private var scrollPosition: Int? = 0
@State private var count: Int = 20
var body: some View {
VStack {
Text("Scroll Position: \(scrollPosition ?? 0)")
.font(.headline)
ScrollView(.vertical, showsIndicators: true) {
VStack(spacing: 8) {
ForEach(0..<count, id: \.self) { index in
Text("Tick \(index)")
.frame(height: 30)
.id(index)
}
}
.scrollTargetLayout()
.padding(.vertical, 50)
}
.scrollTargetBehavior(.viewAligned)
.scrollPosition(id: $scrollPosition)
.frame(height: 300)
.border(Color.gray)
Button("+1") {
withAnimation {
scrollPosition = min((scrollPosition ?? 0) + 1, count - 1)
}
}
.padding(.top)
}
.padding()
}
}
#Preview {
BrokenVerticalScrubberDemo()
}
相反,如果我使用ScrollViewReader
解决方法,它会在点击 2 次“+”按钮后开始滚动。
import SwiftUI
struct SomeWhatWorkingVerticalScrubberDemo: View {
@State private var scrollPosition: Int = 0
@State private var count: Int = 20
var body: some View {
VStack {
Text("Scroll Position: \(scrollPosition)")
.font(.headline)
ScrollView(.vertical, showsIndicators: true) {
ScrollViewReader { scrollViewProxy in
VStack(spacing: 8) {
ForEach(0..<count, id: \.self) { index in
Text("Tick \(index)")
.frame(height: 30)
.id(index)
}
}
.padding(.vertical, 50)
.onChange(of: scrollPosition) { newPosition in
withAnimation {
scrollViewProxy.scrollTo(newPosition, anchor: .center)
}
}
}
}
.frame(height: 300)
.border(Color.gray)
Button("+1") {
scrollPosition = min(scrollPosition + 1, count - 1)
}
.padding(.top)
}
.padding()
}
}
#Preview {
SomeWhatWorkingVerticalScrubberDemo()
}