带有切换的SwiftUI onDelete列表

时间:2020-07-17 07:00:14

标签: list foreach swiftui

这是我关于这个问题的第三个问题。到目前为止,还没有解决方案没有崩溃。我想在“ Toggles”列表上滑动删除。我的(简化)代码如下所示:

struct Item: Identifiable {
    var id = UUID()
    var isOn: Bool
}
struct ContentView: View {
    @State var items = [Item(isOn: true) , Item(isOn: false), Item(isOn: false)]
    
    var body: some View {
        NavigationView {
            List {
                ForEach(items) {item in
                        Toggle(isOn: self.selectedItem(id: item.id).isOn)
                        {Text("Item")}
                }.onDelete(perform: delete)
            }
        }
    }
    
    func delete(at offsets: IndexSet) {
        self.items.remove(atOffsets: offsets)
    }
    
    func selectedItem(id: UUID) -> Binding<Item> {
        guard let index = self.items.firstIndex(where: {$0.id == id}) else {
            fatalError("Item does not exist")
        }
        return self.$items[index]
    }
    
}

我尝试了不同的解决方案,例如.indices.enumerated()并遍历索引。 func selectedItem()的解决方案来自https://troz.net/post/2019/swiftui-data-flow/,这是从item获取可绑定对象的好主意。

如果我尝试滑动删除列表项,我总是会收到此错误:

Thread 1: Fatal error: Index out of range

我真的很想了解为什么会这样,但是XCodes错误消息并没有真正的帮助。我在此处SwiftUI ForEach with .indices() does not update after onDelete(请参阅评论)和此处SwiftUI: Index out of range when deleting cells with toggle发表了类似的问题。

我真的希望有人能在这个问题上有所帮助,因为我试图在互联网上找到解决方案已有几天,但没有一个建议的解决方案真正为我解决。

谢谢Nico

1 个答案:

答案 0 :(得分:2)

这是固定的代码部分(已通过Xcode 11.4 / iOS 13.4测试)

func selectedItem(id: UUID) -> Binding<Item> {
    guard let index = self.items.firstIndex(where: {$0.id == id}) else {
        fatalError("Item does not exist")
    }

    // Don't use direct biding to array element as it is preserved and
    // result in crash, use computable standalone binding instead !!
    return Binding(get: {self.items[index]}, set: {self.items[index] = $0})
}