SwiftUI使用Toggle的onDelete列表

3

这是我第三次关于这个问题的提问。到目前为止,还没有一个不会崩溃的解决方案。我想在一个带有切换开关的列表上进行滑动删除操作。我的(简化后的)代码看起来像这样:

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

我非常希望能够理解为什么会出现这种情况,但 XCode 的错误信息并没有真正有所帮助。我在这里发布了类似的问题:SwiftUI ForEach with .indices() does not update after onDelete(请参见评论),以及SwiftUI: Index out of range when deleting cells with toggle

我真的希望有人能够解决这个问题,因为我已经在网上寻找解决方案几天了,但是并没有一个建议的解决方案能真正解决我的问题。

谢谢,Nico

1个回答

1
这是代码的固定部分(已在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})
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接