gpt4 book ai didi

ios - SwiftUI:创建 CoreData 对象后无法关闭工作表

转载 作者:行者123 更新时间:2023-12-05 08:30:31 26 4
gpt4 key购买 nike

我正在尝试创建一个具有两个 View 的非常基本的应用程序。主视图在 NavigationView 中显示 CoreData 对象,并有一个工具栏按钮可以打开“添加项目”模式表。 “添加项目”工作表应该能够插入一个新的 CoreData 对象并自行关闭。我观察到的是,只要不插入 CoreData 对象,就可以关闭模​​态表,但是一旦它与 CoreData 交互,我关闭该表的所有尝试都不再有效。此外,当工作表创建 CoreData 对象时,出现以下错误:

[Presentation] Attempt to present <TtGC7SwiftUI22SheetHostingControllerVS_7AnyView: 0x7f8fcbc49a10> on <TtGC7SwiftUI19UIHostingControllerGVS_15ModifiedContentVS_7AnyViewVS_12RootModifier_: 0x7f8fcbd072c0> (from <TtGC7SwiftUI19UIHostingControllerGVS_15ModifiedContentVVS_22_VariadicView_Children7ElementGVS_18StyleContextWriterVS_19SidebarStyleContext__: 0x7f8fbbd0ba80>) which is already presenting <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"),那么在工作表上添加项目将不再打印出错误或中断工作表的关闭。所以这个问题在某种程度上与在主表上显示数据有关。但显然我确实需要实际显示数据,这似乎是一个非常常见和基本的模式。我做错了吗?

最佳答案

您的 .sheet 放置在 ToolbarItem 上。只需在 NavigationView 上更改它即可。

这是 ContentView 的主体

var body: some View {
NavigationView {
List {
//Text("static text")

ForEach(items, id:\.self) { 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)
}

}
}

关于ios - SwiftUI:创建 CoreData 对象后无法关闭工作表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64081833/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com