我可以创建一个可以被多个 ContentView 使用的通用 ObservableObject 类吗?

nis*_*ngh 4 ios swift swiftui xcode11 combine

嗨,我只是想知道是否可以创建一个通用类来确认 ObservableObject 协议,它可以被多个 ContentViews 使用。

如果我能做到这一点,那么我将能够使我的 ContentView 和 Model 类完全通用且可重用。

我想实现的一个例子:

protocol ContentViewModelType: ObservableObject {
    var propertyToInitialiseView: [String] { get }
}

struct ContentView: View {
    @ObservedObject var viewModel: some ViewModel

    var body: some View {
        Text("Hello World")
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我能做到这一点,任何类都可以实现 ContentViewModelType 并成为 ContentView 的模型,这使得它具有通用性和可重用性。例如

class ViewModel: ObservableObject {
    var objectWillChange = PassthroughSubject<ViewModel, Never>()
}
Run Code Online (Sandbox Code Playgroud)

但是当我尝试初始化 ContentView 时,xcode 给了我一个类型错误。

在此处输入图片说明

我认为引入一些关键字的全部意义在于,我们可以将协议作为类型用于那些具有关联类型作为要求的协议,因此这应该可以工作。但它给出了一个错误。

如果有人对此问题有任何参考资料或知识可以分享或可能有解决方案,那就太好了。

提前致谢。

rod*_*elp 7

试图理解你的问题,我不太确定我理解意图......但是要创建一个采用通用视图模型的视图(基于您之前的协议),您将需要以下代码:

protocol ViewModelWithProperties: ObservableObject {
    var properties: [String] { get }
}

struct SomeView<T>: View where T: ViewModelWithProperties {
// this can also be written as 
// struct SomeView<T: ViewModelWithProperties>: View {
    @ObservedObject var item: T

    var body: some View {
        VStack {
            ForEach(item.properties, id: \.self) {
                Text($0)
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

要使用此实例,您需要:

struct ContentView: View {
    var body: some View {
        SomeView(item: MyViewModel())
    }
}
Run Code Online (Sandbox Code Playgroud)

正如其他答案之一所述,some用于不透明类型,它不会使您的代码通用。