如何使用CoreData实例化UIHostingController?

问题描述

作为一个长期的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”(...)。

...还是这根本不可能? (还)

解决方法

这是最快的精打细算解决方案-只需使用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))
    }
}
,

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)
    }
}

我不确定这是否适合您的情况,但请尝试。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...