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

List SwiftUI线程1:致命错误:索引超出范围,list,foreach,swiftui,navigationlink,List,Foreach,Swiftui,Navigationlink,在下面的代码中,在SubView1中滑动删除行时出错 class Model: ObservableObject { @Published var items: [Item] init(name: String, items: [Item]) { self.items = items } func delete(at offsets: IndexSet) { self.items.remove(atOffsets

在下面的代码中,在
SubView1
中滑动删除行时出错

class Model: ObservableObject {
    @Published var items: [Item]
    
    init(name: String, items: [Item]) {
        self.items = items
    }
    
    func delete(at offsets: IndexSet) {
        self.items.remove(atOffsets: offsets)
    }
}

class Item: Identifiable, ObservableObject, Equatable {
    static func == (lhs: Item, rhs: Item) -> Bool {
        return lhs.id == rhs.id
    }
    
    var id = UUID()
    var itemName: String
    @Published var subItems: [SubItem]
    
    init(itemName: String, payments: [SubItem]) {
        self.itemName = itemName
        self.subItems = payments
    }
    
    func delete(at offsets: IndexSet) {
        self.subItems.remove(atOffsets: offsets)
    }
}

class SubItem: Identifiable, ObservableObject, Equatable {
    static func == (lhs: SubItem, rhs: SubItem) -> Bool {
        return lhs.id == rhs.id
    }
    
    var id = UUID()
    var isOn: Bool
    
    init(isOn: Bool) {
        self.isOn = isOn
    }
}


struct MainView: View {
    @EnvironmentObject var model: Model
    
    var body: some View {
        NavigationView {
            List {
                ForEach(model.items) {item in
                    NavigationLink(destination: SubView1(item: self.$model.items[self.model.items.firstIndex(of: item) ?? 0])) {
                        HStack{
                            Text(item.itemName)
                            ForEach(item.subItems) {subItem in
                                Text(subItem.isOn ? "True": "False")
                            }
                        }
                    }
                }.onDelete(perform: model.delete)
            }
        }
    }

}
// Here ------>
struct SubView1: View {
    @Binding var item: Item
    var body: some View {
        List {
            ForEach(0..<item.subItems.count) {index in
                NavigationLink(destination: SubView2(subItem: self.$item.subItems[index])) {
                    ToggleView(subItem: self.$item.subItems[index])
                }
                
            }.onDelete(perform: item.delete)
        }
    }
}

struct SubView2: View {
    @Binding var subItem: SubItem
    var body: some View {
        Toggle(isOn: $subItem.isOn) {
            Text("Toggle-Text")
        }
    }
}


struct ToggleView: View {
    @Binding var subItem: SubItem
    var body: some View {
        Toggle(isOn: $subItem.isOn) {
            Text("Toggle-Text")
        }
    }
}
我还为
子视图1
尝试了另一个代码:

struct SubView1: View {
    @Binding var item: Item
    var body: some View {
        List {
            ForEach(item.subItems) {subItem in
                NavigationLink(destination: SubView2(subItem: self.$item.subItems[self.item.subItems.firstIndex(of: subItem) ?? 0])) {
                    ToggleView(subItem: self.$item.subItems[self.item.subItems.firstIndex(of: subItem) ?? 0])
                }
                
            }.onDelete(perform: item.delete)
        }
    }
}

这是为什么?

很遗憾,您的代码没有编译,我不想寻找错误。->提供一个编译和运行示例,这样我们就可以尝试解决问题,而不是首先必须解决编译问题

一般来说,我建议您不要对索引为空的数组执行操作。尤其是你知道的那些在运行时被修改的。 至少在执行操作之前对其进行测试。仅在数组为最终数组时使用直接索引,否则索引超出范围的风险太高

对于您的
onDelete
尝试使用这种方法:

List {
    ForEach(listItems, id: \.self) { (item) in
        Text(item)
    }.onDelete { (indexSet) in
        self.listItems.remove(atOffsets: indexSet)
    }
}
更多信息请点击此处:

要不使用不安全的索引执行操作,请尝试以下操作:

if let index = self.myData.firstIndex(of: self.item) {
       self.myData.remove(at: index)
}
更多信息请点击此处:

if let index = self.myData.firstIndex(of: self.item) {
       self.myData.remove(at: index)
}