Swiftui 快捷方式:onDelete不';无法正确更新用户界面

Swiftui 快捷方式:onDelete不';无法正确更新用户界面,swiftui,Swiftui,当我使用onDelete()删除数组元素时,它会删除数据中的正确项,但会删除UI上的最后一项。我看到了,但我已经在使用它推荐的东西了。有什么建议吗 struct ContentView: View { @State var items = ["One", "Two", "Three"] var body: some View { Form{ ForEach(items.i

当我使用
onDelete()
删除数组元素时,它会删除数据中的正确项,但会删除UI上的最后一项。我看到了,但我已经在使用它推荐的东西了。有什么建议吗

struct ContentView: View {
    @State var items = ["One", "Two", "Three"]
    
    var body: some View {
        Form{
            ForEach(items.indices, id:\.self){ itemIndex in
                
                let item = self.items[itemIndex]
                
                EditorView(container: self.$items, index: itemIndex, text: item)
                
            }.onDelete(perform: { indexSet in

                self.items.remove(atOffsets: indexSet)

            })
        }
    }
}
以下是EditorView结构:

struct EditorView : View {
    var container: Binding<[String]>
    var index: Int

    @State var text: String
    
    var body: some View {
        TextField("Type response here", text: self.$text, onCommit: {
            self.container.wrappedValue[self.index] = self.text
            
        })
    }
}
结构编辑器视图:视图{ var容器:绑定 var指数:Int @状态变量文本:字符串 var body:一些观点{ TextField(“在此处键入响应”,文本:self.$text,onCommit:{ self.container.wrappedValue[self.index]=self.text }) } }
您的
ForEach
正在数组的
索引上循环,因此这就是
SwiftUI
用来识别它们的方法。删除项目时,数组的索引会减少一个,因此SwiftUI会将其解释为最后一个已删除

要正确执行此操作,您应该循环查看具有唯一
id
可识别
项目列表。在这里,我创建了一个名为
MyItem
struct
,它保存原始
字符串和唯一生成的
id
。我使用
.map(MyItem.init)
将项目转换为
[MyItem]

另外,您的代码需要循环中的索引,因此循环
数组(items.enumerated())
,这将为您提供一个
(偏移量,元素)
元组数组。然后告诉SwiftUI使用
\.element.id
作为
id

请注意,
EditorView
现在接受一个
MyItem
数组

通过这些更改,SwiftUI将能够识别您从列表中删除的项目,并正确更新UI

struct MyItem: Identifiable {
    var name: String
    let id = UUID()
}

struct ContentView: View {
    @State var items = ["One", "Two", "Three"].map(MyItem.init)
    
    var body: some View {
        Form{
            ForEach(Array(items.enumerated()), id: \.element.id) { index, item in
                
                EditorView(container: self.$items, index: index, text: item.name)
                
            }.onDelete(perform: { indexSet in
                
                self.items.remove(atOffsets: indexSet)
            })
        }
    }
}

struct EditorView : View {
    var container: Binding<[MyItem]>
    var index: Int
    
    @State var text: String
    
    var body: some View {
        TextField("Type response here", text: self.$text, onCommit: {
            self.container.wrappedValue[self.index].name = self.text
        })
    }
}
struct MyItem:可识别{
变量名称:String
设id=UUID()
}
结构ContentView:View{
@状态变量items=[“一”、“二”、“三”].map(MyItem.init)
var body:一些观点{
形式{
ForEach(数组(items.enumerated()),id:\.element.id){index,中的项
EditorView(容器:self.$items,索引:index,文本:item.name)
}.onDelete(执行:{indexSet in
self.items.remove(atoffset:indexSet)
})
}
}
}
结构编辑器视图:视图{
var容器:绑定
var指数:Int
@状态变量文本:字符串
var body:一些观点{
TextField(“在此处键入响应”,文本:self.$text,onCommit:{
self.container.wrappedValue[self.index].name=self.text
})
}
}

谢谢,这就解决了问题。此外,如果您对了解可识别资源有任何建议,我们将不胜感激。正如您在本教程中所看到的,
可识别
非常有效,因为您可以仅迭代列表,但在您的情况下,您还需要索引,因此,在这种情况下,我们没有真正使用
可识别
协议,因为我们在
ForEach
中明确指定了id。感谢您的回答和建议。我花了几个小时用
identification
尝试了不同的东西&我想我已经很好地掌握了它。