【问题标题】:SwiftUI list 'NSInternalInconsistencyException', reason: 'attempt to insert section 0 but there are only 0 sections after the update'SwiftUI 列表“NSInternalInconsistencyException”,原因:“尝试插入第 0 节,但更新后只有 0 节”
【发布时间】:2021-10-26 11:37:34
【问题描述】:

我有以下代码。它需要 Xcode 13 beta 来编译。在 iOS 14 上运行并点击“插入数据”按钮时,它会崩溃并出现以下错误:

libc++abi: terminating with uncaught exception of type NSException
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to insert section 0 but there are only 0 sections after the update'
terminating with uncaught exception of type NSException
class MyViewModel: ObservableObject {
    @Published var components: [String] = []
}

struct ComponentListContent: View {
    @EnvironmentObject var viewModel: MyViewModel

    var body: some View {
        ForEach(self.$viewModel.components, id: \.self) { $component in // This syntax requires Xcode 13
            TextField("Component Name", text: $component)
        }
    }
}

struct MySheet: View {
    @EnvironmentObject var viewModel: MyViewModel
    @State private var isSheetPresented = true
    @State var isEditing = false

    var body: some View {
        NavigationView {
            List {
                ComponentListContent()
            }
            .environment(\.editMode, .constant(self.isEditing ? EditMode.active : EditMode.inactive))
            .navigationBarItems(trailing:
                Button(action: { self.isEditing.toggle() }, label: {
                    Text(self.isEditing ? "Done" : "Edit")
                })
            )
            .sheet(isPresented: self.$isSheetPresented) {
                Button("Insert data") {
                    self.isSheetPresented.toggle()
                    self.viewModel.components = ["a", "b", "c", "d"]
                }
            }
            .navigationBarTitle("New Analysis", displayMode: .inline)
        }
        .navigationViewStyle(StackNavigationViewStyle())
    }
}

struct ContentView: View {
    var body: some View {
        Text("Hello, world!")
            .sheet(isPresented: .constant(true)) {
                MySheet()
                    .environmentObject(MyViewModel())
            }
    }
}

如果我将ComponentListView 的主体移动到MySheet,则不会发生错误。如果我删除.environment(\.editMode....,它也不会发生。但是我确实需要这两个。是否存在我遗漏的潜在问题?

【问题讨论】:

    标签: swiftui xcode13


    【解决方案1】:

    这似乎是由于.constant 绑定而发生的。

    我建议您切换到存储EditMode 而不是Bool,并使用将修改它的getter/setter 定义isEditing。你可以对@Binding 做同样的事情,但这看起来更干净一些。

    @State var editMode = EditMode.inactive
    var isEditing: Bool {
        get {
            editMode.isEditing
        }
        nonmutating set {
            if newValue {
                editMode = .active
            } else {
                editMode = .inactive
            }
        }
    }
    
    // subscribe
    .environment(\.editMode, $editMode)
    

    【讨论】:

    • 哇...我很惊讶你能抓住这个。您能解释一下为什么您的更改可以防止崩溃吗?列表的底层实现崩溃,因为它无法以某种方式更新编辑模式?
    • @BartvanKuik 是的,我想当表格视图重新出现时它会改变这个变量。我想说将.constant 传递给environment 总是一个坏主意,因为环境变量意味着要在应用程序的不同部分进行更改。尤其是在处理系统问题时。
    猜你喜欢
    • 2017-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多