我创建了一个简单的垂直列表,其中包含要显示的项目。
问题是当我通过 . 在列表顶部插入项目时insertAtTop()
。滚动视图不会停留在同一个位置。
观看视频: https: //streamable.com/i7ywab
如何使滚动视图保持在同一位置?
这是示例代码。
struct TestView: View {
@State private var items: [Item] = []
var body: some View {
NavigationView {
ScrollView {
LazyVStack {
ForEach(items, id: \._id) { item in
Text(item.text)
.background(Color.green)
.padding(.bottom, 10)
}
}
}
.navigationBarItems(trailing: HStack {
Button("[Insert at top]", action: {
insertAtTop()
})
Spacer(minLength: 20)
Button("[Load]", action: {
load()
})
})
.navigationTitle("Item List")
}
}
private func load() {
items = (1...50).map { _ in Item() }
}
private func insertAtTop() {
let newItems = (1...20).map { _ in Item() }
items.insert(contentsOf: newItems, at: 0)
}
}
struct TestView_Previews: PreviewProvider {
static var previews: some View {
TestView()
}
}
struct Item {
var _id = UUID()
var text = UUID().uuidString.prefix(5)
}
Run Code Online (Sandbox Code Playgroud)
仅当您在列表顶部添加新视图时,问题似乎才会出现。如果您修改或替换现有视图,则不会有问题。
...所以一种解决方法是在负方向上具有大量视图(例如 10000)的占位符数组上循环 ForEach。然后在 ForEach 中,检查索引以查看它是否存在于真实/非占位符数组中。
如果是 -> 真实视图 如果不是 -> 廉价视图(例如具有正确背景颜色且高度为 1 的 Rectangle())。
LazyVStack {
ForEach(placeholderIndices, id: \.self) { index in
if indices.contains(index) {
REAL VIEW
} else {
Rectangle()
.fill(Color.bg)
.frame(height: 0)
}
}
}
Run Code Online (Sandbox Code Playgroud)
当您扩展视图时,placeholderIndices 保持不变;只有“真实”指数发生变化
归档时间: |
|
查看次数: |
1944 次 |
最近记录: |