如何为泛型类返回不透明类型?
func makeFAQController() -> UIHostingController<some View> {
let viewModel = FAQViewModel()
let view = FAQView().environmentObject(viewModel)
let controller = UIHostingController(rootView: view)
return controller
}
错误:无法转换类型为'UIHostingController<某些视图>'以键入'UIHostingController<FAQView>'强制
func makeFAQController() -> UIHostingController<FAQView> {
let viewModel = FAQViewModel()
let view = FAQView().environmentObject(viewModel)
let controller = UIHostingController(rootView: view)
return controller
}
无法转换'UIHostingController<类型的值;某些视图>'到类型'UIHostingController<FAQView>'强制
如果可能的话,我希望避免类型擦除。
您应该返回基类(没有比base类更通用的了,可能只有元NSObject
(,所以
func makeFAQController() -> UIViewController { // << here !!
let viewModel = FAQViewModel()
let view = FAQView().environmentObject(viewModel)
let controller = UIHostingController(rootView: view)
return controller
}
您还可以在此处使用类型擦除的AnyView
:
func makeFAQController() -> UIHostingController<AnyView> {
let viewModel = FAQViewModel()
let view = FAQView().environmentObject(viewModel)
let controller = UIHostingController(rootView: AnyView(view))
return controller
}
避免AnyView
的另一种方法是使makeFaqController
方法的封闭类通用,并在其中存储一个闭包/viewBuilder,用作创建时的视图宿主:
class FAQMaker<U: View> {
fileprivate let _prepare: (FAQView) -> U
init(_ prepare: @escaping (FAQView) -> U) {
self._prepare = prepare
}
func makeFAQController() -> UIHostingController<U> {
let prepared = _prapare(FAQView())
return UIHostingController(rootView: prepared)
}
}
前一种方法适用于将SwiftUI视图封装到UICollectionReusableView
中。