I am defining a SwiftUI view with an associated ViewModel protocol type. However, I getting this error while building Type 'any MyViewModelType' cannot conform to 'MyViewModelType'
.
Here's my full code.
protocol MyViewModelType: ObservableObject {
var loadData: CGFloat { get }
}
struct MyView<ViewModel>: View where ViewModel: MyViewModelType {
@ObservedObject private var viewModel: ViewModel
init(viewModel: any MyViewModelType) {
self.viewModel = viewModel as! ViewModel
}
var body: some View {
Text("Hi")
}
}
class SubscriptionViewV2Controller: UIHostingController<MyView<MyViewModelType>> {
init(viewModel: any MyViewModelType) {
super.init(rootView: MyView(viewModel: viewModel))
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationController?.isNavigationBarHidden = true
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return .darkContent
}
@MainActor @objc required dynamic init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
I am not sure what am I doing wrong?
Additionally, I dont know why Xcode would throw error here
init(viewModel: any MyViewModelType) {
self.viewModel = viewModel as! ViewModel
}
Because of that error, I need to force cast viewModel
assignment.
CodePudding user response:
SwiftUI generics need one concrete Type to work with. This could be any MyViewModelType
. But you have to specify that it will be only one specific. any
is the exact opposite.
protocol MyViewModelType: ObservableObject {
var loadData: CGFloat { get }
}
struct MyView<T>: View where T: MyViewModelType {
@ObservedObject private var viewModel: T
init(viewModel: T) {
self.viewModel = viewModel
}
var body: some View {
Text("Hi")
}
}
class SubscriptionViewV2Controller<T>: UIHostingController<MyView<T>> where T: MyViewModelType {
init(viewModel: T) {
super.init(rootView: MyView(viewModel: viewModel))
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationController?.isNavigationBarHidden = true
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return .darkContent
}
@MainActor @objc required dynamic init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
This could shed some light on it.
Also this.