在SwiftUI中将TextField与ForEach一起使用

在SwiftUI中将TextField与ForEach一起使用,swiftui,swiftui-foreach,Swiftui,Swiftui Foreach,我正在尝试使用ForEach显示文本字段的动态列表。以下代码按预期工作:我可以添加/删除文本字段,并且绑定正确。但是,当我在可观察对象视图模型中移动项时,它不再工作,并且会因索引超出范围错误而崩溃。为什么呢?我怎样才能让它工作 struct ContentView:View{ @状态变量项=[“A”、“B”、“C”] var body:一些观点{ VStack{ ForEach(items.index,id:\.self){中的索引 FieldView(值:绑定(获取:{ 项目[索引] },设置

我正在尝试使用
ForEach
显示文本字段的动态列表。以下代码按预期工作:我可以添加/删除文本字段,并且绑定正确。但是,当我在
可观察对象
视图模型中移动
时,它不再工作,并且会因
索引超出范围
错误而崩溃。为什么呢?我怎样才能让它工作

struct ContentView:View{
@状态变量项=[“A”、“B”、“C”]
var body:一些观点{
VStack{
ForEach(items.index,id:\.self){中的索引
FieldView(值:绑定(获取:{
项目[索引]
},设置:{newValue in
项目[索引]=新值
})) {
项目。删除(位于:索引)
}
}
按钮(“添加”){
项目。附加(“”)
}
}
}
}
结构字段视图:视图{
@绑定变量值:字符串
让onDelete:()->Void
var body:一些观点{
HStack{
文本字段(“项目”,文本:$value)
按钮(操作:{
onDelete()
},标签:{
图像(系统名称:“乘法”)
})
}
}
}
我尝试使用的视图模型:

类视图模型:可观察{
@已发布的变量项:[字符串]
}
@ObservedObject变量viewModel:viewModel
我发现许多问题都与同一个问题有关,但我的案例一个问题也无法解决。其中一些没有提到
文本字段
,另一些则不起作用(不再?)


非常感谢

通过检查
绑定中的边界
,您可以解决以下问题:

struct ContentView: View {
    @ObservedObject var viewModel: ViewModel = ViewModel(items: ["A", "B", "C"])
    
    var body: some View {
        VStack {
            ForEach(viewModel.items.indices, id: \.self) { index in
                FieldView(value: Binding<String>(get: {
                    guard index < viewModel.items.count else { return "" } // <- HERE
                    return viewModel.items[index]
                }, set: { newValue in
                    viewModel.items[index] = newValue
                })) {
                    viewModel.items.remove(at: index)
                }
            }
            Button("Add") {
                viewModel.items.append("")
            }
        }
    }
}
struct ContentView:View{
@ObservedObject变量viewModel:viewModel=viewModel(项:[“A”、“B”、“C”])
var body:一些观点{
VStack{
ForEach(viewModel.items.index,id:\.self){中的索引
FieldView(值:绑定(获取:{

保护索引SwiftUI
仍在查找所有
索引,当它试图访问已删除索引处的元素时,找不到导致
索引超出范围的元素错误

为了解决这个问题,我们可以编写一个条件语句,以确保仅当
索引
包含在
索引的集合中时,才搜索
元素

FieldView(value: Binding<String>(get: {
    if viewModel.items.indices.contains(index) {
        return viewModel.items[index]
    } else {
        return ""
    }
}, set: { newValue in
    viewModel.items[index] = newValue
})) {
    viewModel.items.remove(at: index)
}
FieldView(值:Binding(获取:{
如果viewModel.items.Indexs.contains(索引){
返回viewModel.items[索引]
}否则{
返回“”
}
},设置:{newValue in
viewModel.items[index]=newValue
})) {
viewModel.items.remove(位于:索引)
}
上述解决方案解决了这个问题,因为它确保当元素数量(
items.count
)不大于
索引时,不会搜索元素


这正是我所能理解的,但在幕后可能会发生其他事情。

得知这是一个bug,我感到很欣慰。希望下一个版本能够修复它!当使用
List
onDelete
时,它已经起作用了。这也是一个有效的答案!谢谢!