SwiftUI 模态环境

swi*_*fty 5 ios swift swiftui

我真的不明白使用模态时环境是如何工作的。看起来环境对于模态视图是分开的。

\n\n

我使用核心数据制作了一个快速示例,并将对象保存到核心数据。如果我不通过环境,则不会保存对象,并且在尝试保存对象时出现以下错误:\n操作无法完成\xe2\x80\x99。(Foundation._GenericObjCError 错误 0。)

\n\n

如果我在模式环境中传递托管对象上下文,它就会起作用。我注释掉了使它起作用的行。

\n\n

任何人都可以解释为什么会发生这种情况吗?

\n\n
\n    @FetchRequest(fetchRequest: ToDoItem.fetchAllItems()) var items\n    @Environment(\\.managedObjectContext) var managedObjectContext\n    @State var showAddModal = false\n\n\n    var body: some View {\n\n        VStack {\n\n            List(items, id: \\.name) { item in\n                Text(item.name)\n            }\n\n            Button(action: {\n                self.showAddModal.toggle()\n            }) {\n                Text("Add item")\n            }.sheet(isPresented: $showAddModal) {\n                ModalView()\n//                    .environment(\\.managedObjectContext, self.managedObjectContext)\n//                It works if the managed object context is passed in the modal\'s environment\n            }\n        }\n    }\n}\n\nstruct ModalView: View {\n\n    @State var toDoItemName: String = ""\n    @Environment(\\.presentationMode) var presentationMode\n    @Environment(\\.managedObjectContext) var managedObjectContext\n\n    var body: some View {\n\n        VStack {\n            TextField("Item name", text: $toDoItemName)\n            Button(action: {\n                let toDoItem = ToDoItem(context: self.managedObjectContext)\n                toDoItem.name = self.toDoItemName\n                do {\n                    try self.managedObjectContext.save()\n                } catch {\n                    print(error.localizedDescription)\n                }\n                self.presentationMode.wrappedValue.dismiss()\n            }) {\n                Text("Add")\n            }\n        }\n    }\n}```\n
Run Code Online (Sandbox Code Playgroud)\n

Dra*_*gos 0

当您在SwiftUI中创建第一个视图时,框架会为其生成一个环境。SwiftUI 使用环境来存储不同的系统设置,例如配色方案管理对象上下文和特定于应用程序的内容(例如默认字体)。除了我们的自定义环境对象之外,所有系统设置特定于应用程序的内容都是预定义的环境值在这里,您可以检查环境值的完整集合)。要记住的一件重要的事情是每个视图都从其父视图继承环境

因此,通过ModalView中的以下代码行,您可以从 ModalView 的环境中获取ManagedObjectContext ,该环境是从呈现它的视图继承的。

@Environment(\.managedObjectContext) var managedObjectContext
Run Code Online (Sandbox Code Playgroud)

此外,当您使用 Coredata 时,您应该注意上下文,尤其是在使用多个上下文时。

提示:如果您转到我们的根视图并设置您可能需要的所有值,您将在整个应用程序中传播它们(作为注入到环境中的值)。

参考:

  • 这就是文档似乎暗示的内容,但这并不是它在实践中的工作方式。通过一个简单的示例以及 SwiftUI 教程可以解决的问题很容易进行演示(在使用 UI 控件教程中,“CategoryHome”视图将环境对象传递到它呈现的“ProfileHost”视图的环境中)。 (2认同)