作为一个长期的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推断正确/合适的类型?
到目前为止我尝试过的。
5 let contentView = MyCoreDataView()
编译/运行,但不包括CoreData。
6 super.init(coder: coder, rootView: contentView as! MyCoreDataView)
编译,但在实例化时崩溃。
无法转换类型为'SwiftUI.ModifiedContent
>'的值(...) 到“ MyHostingController.MyCoreDataView”(...)。
...还是这根本不可能? (还)
答案 0 :(得分:0)
这是最快的精打细算解决方案-只需使用AnyView
类型擦除器即可。
注意:任何视图修饰符都会创建(通常可以创建)不同类型的视图,这就是为什么编译器会抱怨您的情况-类型不同。
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))
}
}
答案 1 :(得分:0)
OOPer在Apple Dev论坛上发布:
如您所见,SwiftUI View的修饰符会返回一些不透明的类型,某些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)
}
}
我不确定这是否适合您的情况,但请尝试。