根据 Apple 关于 的文档ScrollViewReader
,它应该包装滚动视图,而不是嵌套在其中。
Apple 文档中的示例:
@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
wrap a List
of 元素,也可以很方便。文章中的代码示例:
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)
在我使用 view 修饰符之前 using 也不起作用
.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
会导致它在手动滚动列表时触发列表中的元素。