SwiftUI中使用.indices()的ForEach在onDelete后不更新

7
我的问题是:我有一个简单的数组,其中包含一些项目。我想使用 ForEach.indices() 显示这些项目的 List。(原因是我的实际问题涉及 List 中的 Toggle,对于 isOn 绑定,我需要索引来寻址绑定到 EnvironmentObject 的模型)。所以循环遍历数组 items 的解决方案不适用于我的问题。
简化后的初始代码如下:
struct ContentView: View {
    @State var items = ["Item1", "Item2", "Item3"]
    
    var body: some View {
        List {
            ForEach(items.indices) {index in
                Text(self.items[index])
            }.onDelete(perform: deleteItem)
        }
    }
    
    func deleteItem(indexSet: IndexSet) {
        self.items.remove(atOffsets: indexSet)
    }
}

如果我现在尝试滑动删除一行,将会收到以下错误信息:
Thread 1: Fatal error: Index out of range

在闭包内调试index值,我发现items数组的索引没有更新。例如:如果我删除第一行中的"Item 1"并检查删除行后index的值,它返回2而不是预期的数组第一个索引0。这是为什么,我该如何解决这个问题?

谢谢你的帮助!

1个回答

6

只需使用动态内容 ForEach 构造函数 (_ data: .., id: ...)

ForEach(items.indices, id: \.self) {index in   // << here !!
    Text(self.items[index])
}.onDelete(perform: deleteItem)

谢谢你的回答,Asperi。它很好用。现在我尝试了一下你的解决方案,使用一个具有[Item]数组的Model类。而Item是一个符合Identifiable协议并且具有布尔属性的结构体。现在,如果我像上面那样构建相同的视图,一切都很好。但是当我将Text()-视图替换为由布尔值控制的Toggle()时,在删除时我会在AppDelegate内部得到另一个错误:Thread 1: Fatal error: Index out of range。这里发生了什么? - user11960918
这解决了我的问题......传统方法中,在第一个viewLoad中,我的数组有3个元素,并且显示了3个项目......在reload中,数组只有一个项目,但是ForEach遍历了索引0、1、2。即使我在ForEach之前检查了items.count并且它等于1,但还是很奇怪..... - eharo2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接