gpt4 book ai didi

swift - 环境变量未传递给 subview

转载 作者:行者123 更新时间:2023-11-28 13:27:24 24 4
gpt4 key购买 nike

我想开始使用 Core Data 和 SwiftUI,因此使用最新的 Xcode 11.1 GM 创建了一个新的 watchOS 项目。

然后,我复制了两个 persistentContainer & saveContext来自一个新的 iOS 项目(启用了 Core Data),以获得 Core Data 功能。

之后我修改了HostingController返回 AnyView并在环境中设置变量。

class HostingController: WKHostingController<AnyView> {
override var body: AnyView {

let managedObjectContext = (WKExtension.shared().delegate as! ExtensionDelegate).persistentContainer.viewContext


return AnyView(ContentView().environment(\.managedObjectContext, managedObjectContext))
}
}

现在我可以访问 ContentView 中的上下文, 但不在其 subview 中
但这不是它的本意吗?据我所知,所有 subview 都应该从其父 View 继承其环境,对吧?

现在,要在其 subview 中访问它,我只需再次设置环境变量,如下所示:

内容 View .swift

NavigationLink(destination: ProjectsView().environment(\.managedObjectContext, managedObjectContext)) {
HStack {
Image(systemName: "folder.fill")
Text("Projects")
}
}

一旦我删除 ContentView 中的 .environment() 参数,App 就会崩溃,因为没有加载上下文?!

错误信息是Context in environment is not connected to a persistent store coordinator: <NSManagedObjectContext: 0x804795e0> .

项目 View .swift

struct ProjectsView: View {
@Environment(\.managedObjectContext) var managedObjectContext
[...]
}

但是,这不是对的吗?那么,是什么导致了这里的错误?

最佳答案

我能够通过修复 HostingController 并确保在构建 View 之前设置 CoreData 堆栈来解决这个问题。首先,让我们确保 CoreData 堆栈已准备就绪。在 ExtensionDelegate 中:

class ExtensionDelegate: NSObject, WKExtensionDelegate {

let persistentContainer = NSPersistentContainer(name: "Haha")

func applicationDidFinishLaunching() {
persistentContainer.loadPersistentStores(completionHandler: { (storeDescription, error) in
// handle this
})
}
}

当这个属性是 lazy 时我遇到了麻烦,所以我明确地设置了它。如果您遇到计时问题,请使用信号量同步调用 loadPersistentStores 进行调试,然后弄清楚如何延迟 nib 实例化,直到稍后调用闭包。

接下来,让我们通过引用常量 View 上下文来修复 HostingControllerWKHostingController 是一个对象,而不是结构。所以现在我们有:

class HostingController: WKHostingController<AnyView> {

private(set) var context: NSManagedObjectContext!

override func awake(withContext context: Any?) {
self.context = (WKExtension.shared().delegate as! ExtensionDelegate).persistentContainer.viewContext
}

override var body: AnyView {
return AnyView(ContentView().environment(\.managedObjectContext, context))
}
}

现在,任何 subview 都应该可以访问 MOC。以下现在对我有用:

struct ContentView: View {

@Environment(\.managedObjectContext) var moc: NSManagedObjectContext

var body: some View {
VStack {
Text("\(moc)")
SubView()
}
}
}

struct SubView: View {

@Environment(\.managedObjectContext) var moc: NSManagedObjectContext

var body: some View {
Text("\(moc)")
.foregroundColor(.red)
}
}

您应该看到 MOC 的地址在上方为白色,在下方为红色,没有SubView 上调用 .environment

关于swift - 环境变量未传递给 subview ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58113776/

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