在SwiftUI中使用模式视图崩溃删除列表中的项目

时间:2020-06-21 01:20:47

标签: swift swiftui swiftui-list

当尝试从模式视图中删除列表中的项目时,崩溃Thread 1: Fatal error: Index out of range

例如,

  1. 删除1-> 2-> 3崩溃
  2. 删除2-> 1崩溃
  3. 删除3崩溃

如果注释掉文本字段部分,则不会崩溃。不太确定发生了什么...

struct ContentView: View {
    @State var strs = ["1", "2", "3"]
    @State var showingDetail: Bool = false
    var body: some View {
        List {
            ForEach(Array(strs.enumerated()), id: \.element) { index, str in
                VStack {
                    Button(action: {
                        self.showingDetail.toggle()
                    }) {
                        Text("show modal")
                            .sheet(isPresented: self.$showingDetail) {
                                ModalView(showingDetail: self.$showingDetail, strs:self.$strs,
                                          index: index)
                        }
                        TextField("", text:self.$strs[index])
                    }
                }
            }
        }
    }
}

struct ModalView: View {
    @Binding var showingDetail: Bool
    @Binding var strs: [String]
    var index: Int = 0
    var body: some View {
        Button(action: {
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                self.strs.remove(at: self.index)
            }
            self.showingDetail.toggle()
        }) {
            Text("delete")
        }
    }
}

2 个答案:

答案 0 :(得分:0)

删除数组中的元素时,数组中的元素数会减少。因此,当您删除第一个元素(即索引0)时,只剩下2个了。现在,您可以删除索引1处的元素(它是最后一个元素),并且数组在索引0处只剩下1个元素。因此,当您尝试访问索引2处的第三个元素时,您会崩溃。如果要顺序删除元素,则从索引0删除,直到数组为空。因此,如果数组中有3个元素,则必须删除0-> 0-> 0。

答案 1 :(得分:0)

该问题归因于视图更新顺序。请为TextField

使用以下变体
TextField("", text: Binding(get: { self.strs[index] },
                            set: { self.strs[index] = $0 }))