【发布时间】:2021-01-12 20:02:36
【问题描述】:
我正在尝试创建一个具有两个视图的非常基本的应用程序。主视图在 NavigationView 中显示 CoreData 对象,并具有用于打开“添加项目”模式表的工具栏按钮。 “添加项目”表应该能够插入一个新的 CoreData 对象并自行关闭。我观察到的是,只要模式表不插入 CoreData 对象,它就可以被关闭,但是一旦它与 CoreData 交互,我所有试图关闭工作表的尝试都不再有效。此外,当工作表创建 CoreData 对象时,我收到以下错误:
[演示]尝试本 TtGC7SwiftUI22SheetHostingControllerVS_7AnyView EM>:0x7f8fcbc49a10>上 TtGC7SwiftUI19UIHostingControllerGVS_15ModifiedContentVS_7AnyViewVS_12RootModifier EM> _:0x7f8fcbd072c0>(来自 TtGC7SwiftUI19UIHostingControllerGVS_15ModifiedContentVVS_22_VariadicView_Children7ElementGVS_18StyleContextWriterVS_19SidebarStyleContext EM> __:0x7f8fbbd0ba80> ) 这已经在呈现 TtGC7SwiftUI22SheetHostingControllerVS_7AnyView: 0x7f8fcbd310b0>。
我使用的大部分代码都是 Xcode 自己的样板代码,以及从网络上借来的常见模式。你能帮我调试一下吗?
为了重现,在 Xcode 12 中,使用 CoreData 创建一个新的 SwiftUI iOS 应用程序。将 ContentView.swift 替换为:
import SwiftUI
import CoreData
struct ContentView: View {
@Environment(\.managedObjectContext) private var viewContext
@FetchRequest(
sortDescriptors: [NSSortDescriptor(keyPath: \Item.timestamp, ascending: true)],
animation: .default)
private var items: FetchedResults<Item>
@State var showingSheet: Bool = false
var body: some View {
NavigationView {
List {
//Text("static text")
ForEach(items) { item in
Text("Item at \(item.timestamp!, formatter: itemFormatter)")
}
.onDelete(perform: deleteItems)
}
.navigationTitle("List of items")
.toolbar {
ToolbarItem(placement: .primaryAction) {
Button(action: {
showingSheet = true
}) {
Text("Open sheet")
}
.sheet(isPresented: $showingSheet) {
MySheetView(isPresented: $showingSheet)
.environment(\.managedObjectContext, viewContext)
}
}
}
}
}
private func deleteItems(offsets: IndexSet) {
withAnimation {
offsets.map { items[$0] }.forEach(viewContext.delete)
do {
try viewContext.save()
} catch {
let nsError = error as NSError
fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
}
}
}
}
private let itemFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .short
formatter.timeStyle = .medium
return formatter
}()
创建一个新的 MySheetView.swift:
struct MySheetView: View {
@Environment(\.managedObjectContext) private var viewContext
@Binding var isPresented: Bool
var body: some View {
NavigationView {
Form {
Button(action: {
self.isPresented = false
}) {
Text("Dismiss this sheet")
}
Button(action: {
let newItem = Item(context: viewContext)
newItem.timestamp = Date()
do {
try viewContext.save()
} catch {
let nsError = error as NSError
fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
}
}) {
Text("Add Item")
}
}
}
}
}
运行时,如果你点击“打开工作表”,然后你可以点击“关闭此工作表”,它就可以工作了。但是,如果您点击“打开工作表”,然后点击“添加项目”,则会打印错误并且“关闭此工作表”按钮将停止工作。 (您仍然可以向下滑动以关闭工作表。)
我也尝试了presentationmode.wrappedvalue.dismiss()方法,没有成功。
我发现,如果您在主视图上注释掉 ForEach 循环并取消注释 Text("static text"),那么在工作表上添加项目将不再打印出错误或中断工作表的解除。所以这个问题在某种程度上与在主工作表上显示数据有关。但显然我确实需要实际显示数据,这似乎是一种非常常见和基本的模式。我做错了吗?
【问题讨论】:
标签: ios swift core-data swiftui