SwiftUI 列表 'NSInternalInconsistencyException',原因:'attempt to insert section 0 but there are only 0 sections after the update'
SwiftUI list 'NSInternalInconsistencyException', reason: 'attempt to insert section 0 but there are only 0 sections after the update'
我有以下代码。它需要 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....
,它也不会发生。但是我确实需要这两个。是否存在我遗漏的潜在问题?
这似乎是因为 .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)
我有以下代码。它需要 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....
,它也不会发生。但是我确实需要这两个。是否存在我遗漏的潜在问题?
这似乎是因为 .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)