在iOS 15上,ScrollViewReader的scrollTo存在问题,滚动太多。 我有一个按钮和一个日期选择器,点击按钮时我会显示日期选择器,但我想确保日期选择器在屏幕上完全可见,所以我滚动到它。重现问题的代码附在下面:
import SwiftUI
struct ScrollToIssue: View {
@State var showPicker: Bool = false
@State var date: Date = Date()
var body: some View {
ScrollViewReader { scrollViewReader in
ScrollView {
Color.red.frame(height: 400)
Color.yellow.frame(height: 200)
VStack {
Button(action: {
showPicker.toggle()
if showPicker {
DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: {
withAnimation {
scrollViewReader.scrollTo("pickerrrr")
}
})
}
}, label: {
Text("Show picker")
})
if showPicker {
DatePicker(selection: $date,
displayedComponents: .date,
label: { EmptyView() })
.labelsHidden()
.datePickerStyle(GraphicalDatePickerStyle())
.id("pickerrrr")
}
}
.border(Color.green)
Color.blue.frame(height: 500)
}
}
}
}
在 iOS 16/17 上运行良好。还尝试将 ScrollViewReader 移动到 ScrollView 的内部/外部,没有区别,也尝试使用锚点 .bottom,仍然是同样的问题。
我将 Xcode 15.0 与 Iphone 13、iOS 15.5 一起使用
我相信这是 SwiftUI 中的一个错误。
还有很多人已经遇到过同样的问题。 https://developer.apple.com/forums/thread/688230
无论如何,您可以通过使用
LazyVStack
而不是 VStack
来避免此问题。
注意:我还没有更新我的 macOS,所以我使用的是 Xcode 14.3,所以我还没有针对 iOS 17 进行测试。
struct ScrollToIssue: View {
@State var showPicker: Bool = false
@State var date: Date = Date()
var body: some View {
ScrollViewReader { scrollViewReader in
ScrollView {
Color.red.frame(height: 400)
Color.yellow.frame(height: 200)
LazyVStack { // 👀 Instead of VStack
Button(action: {
showPicker.toggle()
if showPicker {
DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: {
withAnimation {
scrollViewReader.scrollTo("pickerrrr")
}
})
}
}, label: {
Text("Show picker")
})
if showPicker {
DatePicker(selection: $date,
displayedComponents: .date,
label: { EmptyView() })
.labelsHidden()
.datePickerStyle(GraphicalDatePickerStyle())
.id("pickerrrr")
}
}
.border(Color.green)
Color.blue.frame(height: 500)
}
}
}
}