根据苹果公司有关
ScrollViewReader
的
文档,它应该包装滚动视图,而不是嵌套在其中。
来自苹果文档的示例:
@Namespace var topID
@Namespace var bottomID
var body: some View {
ScrollViewReader { proxy in
ScrollView {
Button("Scroll to Bottom") {
withAnimation {
proxy.scrollTo(bottomID)
}
}
.id(topID)
VStack(spacing: 0) {
ForEach(0..<100) { i in
color(fraction: Double(i) / 100)
.frame(height: 32)
}
}
Button("Top") {
withAnimation {
proxy.scrollTo(topID)
}
}
.id(bottomID)
}
}
}
func color(fraction: Double) -> Color {
Color(red: fraction, green: 1 - fraction, blue: 0.5)
}
这篇文章也展示了如何使用ScrollViewReader
来包装一个元素的List
,这也很方便。来自该文章的代码示例:
ScrollViewReader { scrollView in
List {
ForEach(photos.indices) { index in
Image(photos[index])
.resizable()
.scaledToFill()
.cornerRadius(25)
.id(index)
}
}
.
.
.
}
对我而言,使用value.scrollTo(entries.count - 1)
不起作用。此外,在使用value.scrollTo(entries.last?.id)
之前,也不起作用,直到我使用
.id(...)
视图修饰符(可能是因为我的条目不符合Identifiable
)。
在使用ForEach
时,这是我正在处理的代码:
ScrollViewReader { value in
ScrollView {
ForEach(state.messages, id: \.messageId) { message in
MessageView(message: message)
.id(message.messageId)
}
}
.onAppear {
value.scrollTo(state.messages.last?.messageId)
}
.onChange(of: state.messages.count) { _ in
value.scrollTo(state.messages.last?.messageId)
}
}
使用onAppear
时需要注意一个重要的问题,那就是在ScrollView
/List
上使用该修饰符而不是在ForEach
中使用。在ForEach
中这样做会导致它在手动滚动列表时触发列表中的元素出现。