如何使用 CoreData 实例化 UIHostingController?
How to Instantiate UIHostingController with CoreData?
作为一个长期的 Obj-C 开发者(自 iPhone OS 2)我决定 SwiftUI 是使用 Swift! ¯\(ツ)/¯
因此,我仍在努力理解一种语言如何在代码中如此类型模糊,而在编译器中如此类型学究!!!
竭尽全力 Swift/SwiftUI 实例化一个 UIHostingController<>,用于 CoreData
class MyCoreDataHostingController : UIHostingController<MyCoreDataView> {
required init?(coder: NSCoder) {//Instantiate From Storyboard
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let contentView = MyCoreDataView().environment(\.managedObjectContext, context)
super.init(coder: coder, rootView: contentView)
//Cannot convert value of type 'some View' to expected argument type 'MyCoreDataView'
}
}
struct MyCoreDataView: View {
var body: some View {
Text("Core Data View")
}
}
如何强制 Swift 推断 correct/appropriate 类型?
到目前为止我已经尝试了什么。
5 let contentView = MyCoreDataView()
Compiles/runs,但不包括 CoreData。
6 super.init(coder: coder, rootView: contentView as! MyCoreDataView)
编译,但在实例化时崩溃。
Could not cast value of type 'SwiftUI.ModifiedContent<MyHostingController.MyCoreDataView, SwiftUI._EnvironmentKeyWritingModifier<__C.NSManagedObjectContext>>' (...)
to 'MyHostingController.MyCoreDataView' (...).
... 或者这根本不可能? (还)
这是最快的 come-in-mind 解决方案 - 只需使用 AnyView
type-eraser.
注意:任何视图修饰符都会创建(通常可以创建)不同类型的视图,这就是编译器在您的情况下抱怨的原因 - 类型不同。
class MyCoreDataHostingController : UIHostingController<AnyView> {
required init?(coder: NSCoder) {//Instantiate From Storyboard
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let contentView = MyCoreDataView().environment(\.managedObjectContext, context)
super.init(coder: coder, rootView: AnyView(contentView))
}
}
OOPer 在 Apple 开发者论坛上发布:
如您所见,SwiftUI View returns 一些不透明类型的修饰符 一些 View 不会向程序员显示,但 Swift 编译器声称匹配每个类型到处...
一种可能的解决方案是创建包装器视图:
class MyCoreDataHostingController : UIHostingController<MyCoreDataViewEnvironmentWrapper> {
required init?(coder: NSCoder) {//Instantiate From Storyboard
let contentView = MyCoreDataViewEnvironmentWrapper()
super.init(coder: coder, rootView: contentView)
}
}
struct MyCoreDataViewEnvironmentWrapper: View {
private let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
var body: some View {
MyCoreDataView().environment(\.managedObjectContext, context)
}
}
或者您可以选择 AnyView 作为包装器:
class MyCoreDataHostingController : UIHostingController<AnyView> {
required init?(coder: NSCoder) {//Instantiate From Storyboard
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let contentView = AnyView(MyCoreDataView().environment(\.managedObjectContext, context))
super.init(coder: coder, rootView: contentView)
}
}
我不确定这是否适用于您的情况,但请尝试。
作为一个长期的 Obj-C 开发者(自 iPhone OS 2)我决定 SwiftUI 是使用 Swift! ¯\(ツ)/¯ 因此,我仍在努力理解一种语言如何在代码中如此类型模糊,而在编译器中如此类型学究!!!
竭尽全力 Swift/SwiftUI 实例化一个 UIHostingController<>,用于 CoreData
class MyCoreDataHostingController : UIHostingController<MyCoreDataView> {
required init?(coder: NSCoder) {//Instantiate From Storyboard
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let contentView = MyCoreDataView().environment(\.managedObjectContext, context)
super.init(coder: coder, rootView: contentView)
//Cannot convert value of type 'some View' to expected argument type 'MyCoreDataView'
}
}
struct MyCoreDataView: View {
var body: some View {
Text("Core Data View")
}
}
如何强制 Swift 推断 correct/appropriate 类型?
到目前为止我已经尝试了什么。
5 let contentView = MyCoreDataView()
Compiles/runs,但不包括 CoreData。
6 super.init(coder: coder, rootView: contentView as! MyCoreDataView)
编译,但在实例化时崩溃。
Could not cast value of type 'SwiftUI.ModifiedContent<MyHostingController.MyCoreDataView, SwiftUI._EnvironmentKeyWritingModifier<__C.NSManagedObjectContext>>' (...) to 'MyHostingController.MyCoreDataView' (...).
... 或者这根本不可能? (还)
这是最快的 come-in-mind 解决方案 - 只需使用 AnyView
type-eraser.
注意:任何视图修饰符都会创建(通常可以创建)不同类型的视图,这就是编译器在您的情况下抱怨的原因 - 类型不同。
class MyCoreDataHostingController : UIHostingController<AnyView> {
required init?(coder: NSCoder) {//Instantiate From Storyboard
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let contentView = MyCoreDataView().environment(\.managedObjectContext, context)
super.init(coder: coder, rootView: AnyView(contentView))
}
}
OOPer 在 Apple 开发者论坛上发布:
如您所见,SwiftUI View returns 一些不透明类型的修饰符 一些 View 不会向程序员显示,但 Swift 编译器声称匹配每个类型到处...
一种可能的解决方案是创建包装器视图:
class MyCoreDataHostingController : UIHostingController<MyCoreDataViewEnvironmentWrapper> {
required init?(coder: NSCoder) {//Instantiate From Storyboard
let contentView = MyCoreDataViewEnvironmentWrapper()
super.init(coder: coder, rootView: contentView)
}
}
struct MyCoreDataViewEnvironmentWrapper: View {
private let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
var body: some View {
MyCoreDataView().environment(\.managedObjectContext, context)
}
}
或者您可以选择 AnyView 作为包装器:
class MyCoreDataHostingController : UIHostingController<AnyView> {
required init?(coder: NSCoder) {//Instantiate From Storyboard
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let contentView = AnyView(MyCoreDataView().environment(\.managedObjectContext, context))
super.init(coder: coder, rootView: contentView)
}
}
我不确定这是否适用于您的情况,但请尝试。