如何从符合协议的静态变量初始化自定义SwiftUI视图

wydwbb8l  于 2023-05-05  发布在  Swift
关注(0)|答案(1)|浏览(206)

我试图通过将View的Type分配给一个符合CustomViewInterface协议的静态变量来实现SwiftUI View的依赖注入。
static var MyCustomView: any CustomViewInterface.Type = CustomView.self
目标是注入任何符合该协议的View,并在接收类中对其进行初始化。
当我在ContentViewbody块中初始化自定义SwiftUI View时,我得到错误
Type 'any CustomViewInterface' cannot conform to 'View'
虽然当我打印出视图类型的type(of:时,它是CustomView(而不是CustomViewInterface),但我不明白为什么当TypeContentViewbody块中初始化时与在DefaultComponentImplementation类的初始化器中初始化时不同。
我的问题是,如何从一个符合协议的静态变量初始化一个自定义SwiftUI视图。最终目标是为SwiftUI视图使用依赖注入。

import SwiftUI

struct ContentView: View {
    let defaultComponenetImplementaion = DefaultComponentImplementation()

    var body: some View {
        VStack {
            CustomView(title: "cat") // this works
            DefaultComponentImplementation.MyCustomView.init(title: "mouse") // error: Type 'any CustomViewInterface' cannot conform to 'View'
        }
    }
}

protocol CustomViewInterface: View {
    var title: String { get set }

    init(title: String)
}

struct CustomView: CustomViewInterface {
    var title: String

    var body: some View {
        Text(title)
    }
}

class DefaultComponentImplementation {
    static var MyCustomView: any CustomViewInterface.Type = CustomView.self
    
    init() {
        print(type(of: DefaultComponentImplementation.MyCustomView.init(title: "cat"))) // prints CustomView
    }
}
nwnhqdif

nwnhqdif1#

不可以,您不能在视图生成器中使用any View,或者在本例中使用any CustomViewInterfaceany CustomViewInterface不符合View。这是因为a rather long story。它基本上归结为这样一个事实,即View具有某些存在类型所不具备的静态要求,如Body关联类型。(any CustomViewInterface).Body不是一个东西。
由于您希望根据元类型属性显示不同类型的视图,因此将它们擦除为AnyView(与any View不同,* 是 * 具体类型)应该可以工作。
添加扩展名以将any CustomViewInterface擦除到AnyView

extension CustomViewInterface{
    func toAnyView() -> AnyView {
        AnyView(self)
    }
}

然后

DefaultComponentImplementation.MyCustomView.init(title: "mouse").toAnyView()

相关问题