List 带切换和导航链接的SwiftUI onDelete列表

List 带切换和导航链接的SwiftUI onDelete列表,list,binding,swiftui,toggle,swiftui-navigationlink,List,Binding,Swiftui,Toggle,Swiftui Navigationlink,我指的是我已经问过的两个问题,Asperi已经很好地回答了这两个问题:, 现在我试图用NavigationLink修改ForEach中的闭包,突然应用程序再次崩溃 线程1:致命错误:索引超出范围 当我尝试滑动删除时 代码: 类模型:ObservableObject{ @已发布变量名称:String @已发布的var项目:[项目] 初始化(名称:字符串,项:[Item]){ self.name=名称 self.items=项目 } } 结构项:可识别{ var id=UUID() 瓦里森:

我指的是我已经问过的两个问题,Asperi已经很好地回答了这两个问题:,

现在我试图用
NavigationLink
修改
ForEach
中的闭包,突然应用程序再次崩溃

线程1:致命错误:索引超出范围

当我尝试滑动删除时

代码:

类模型:ObservableObject{
@已发布变量名称:String
@已发布的var项目:[项目]
初始化(名称:字符串,项:[Item]){
self.name=名称
self.items=项目
}   
}
结构项:可识别{
var id=UUID()
瓦里森:布尔
}
结构ContentView:View{
@环境对象变量模型:模型
var body:一些观点{
导航视图{
名单{
ForEach(model.items){item在
导航链接(目标:详细视图(项:self.makeBinding(id:item.id))){
切换(isOn:self.makeBinding(id:item.id.isOn)
{Text(“切换文本”)}
}
}.onDelete(执行:删除)
}
}
}
func delete(偏移量处:IndexSet){
self.model.items.remove(atoffset:offset)
}
func makeBinding(id:UUID)->Binding{
guard let index=self.model.items.firstIndex(其中:{$0.id==id})else{
fatalError(“此人不存在”)
}
返回绑定(get:{self.model.items[index]},set:{self.model.items[index]=$0})
}
}
结构详细视图:视图{
@绑定变量项:项
var body:一些观点{
切换(isOn:$item.isOn){
文本(“切换文本”)
}
}
}
它不使用
导航链接
切换
。因此,在我看来,在这个闭包中,我只能使用
makeBinding
-函数一次


感谢您的帮助

无论是否使用导航链接,您的代码都会崩溃。有时只有删除数组中的最后一个对象。看起来它仍在尝试从数组中访问索引。与上面链接的示例不同的是,他们没有使用
EnvironmentObject
访问数组。将数组直接存储在
@状态

我提出了一种稍有不同的方法,将项声明为
ObservedObject
,然后简单地将其传递到子视图,在子视图中可以使用它们的值作为绑定,而无需任何函数

我把物品改成了

class Item: ObservableObject {
    var id = UUID()
    var isOn: Bool
    
    init(id: UUID, isOn: Bool)
    {
        self.id = id
        self.isOn = isOn
    }
}
将ContentView更改为此

struct ContentView: View {
    @EnvironmentObject var model: Model
    
    var body: some View {
        NavigationView {
            List {
                ForEach(model.items, id:\.id) {item in
                    NavigationLink(destination: DetailView(item: item)) {
                        Toggler(item: item)
                    }
                }.onDelete(perform: delete)
            }
        }
    }
我将切换外包给了一个不同的视图,在那里我们将ObservedObject传递给,DetailView也是如此

struct Toggler: View {
    @ObservedObject var item : Item
    
    var body : some View
    {
        Toggle(isOn: $item.isOn)
        {Text("Toggle-Text")}
    }
}

struct DetailView: View {
    @ObservedObject var item: Item
    var body: some View {
        Toggle(isOn: $item.isOn) {
            Text("Toggle-Text")
        }
    }
}

它们都将
作为观察对象,并将其用作
切换的绑定

无论是否使用导航链接,您的代码都会崩溃。有时只有删除数组中的最后一个对象。看起来它仍在尝试从数组中访问索引。与上面链接的示例不同的是,他们没有使用
EnvironmentObject
访问数组。将数组直接存储在
@状态

我提出了一种稍有不同的方法,将项声明为
ObservedObject
,然后简单地将其传递到子视图,在子视图中可以使用它们的值作为绑定,而无需任何函数

我把物品改成了

class Item: ObservableObject {
    var id = UUID()
    var isOn: Bool
    
    init(id: UUID, isOn: Bool)
    {
        self.id = id
        self.isOn = isOn
    }
}
将ContentView更改为此

struct ContentView: View {
    @EnvironmentObject var model: Model
    
    var body: some View {
        NavigationView {
            List {
                ForEach(model.items, id:\.id) {item in
                    NavigationLink(destination: DetailView(item: item)) {
                        Toggler(item: item)
                    }
                }.onDelete(perform: delete)
            }
        }
    }
我将切换外包给了一个不同的视图,在那里我们将ObservedObject传递给,DetailView也是如此

struct Toggler: View {
    @ObservedObject var item : Item
    
    var body : some View
    {
        Toggle(isOn: $item.isOn)
        {Text("Toggle-Text")}
    }
}

struct DetailView: View {
    @ObservedObject var item: Item
    var body: some View {
        Toggle(isOn: $item.isOn) {
            Text("Toggle-Text")
        }
    }
}
它们都将
作为观察对象,并将其用作
切换
的绑定