是否可以通过以下方式将视图与视图模型分离?

时间:2020-04-12 11:12:16

标签: swiftui combine

我的目标是两件事: 1.根据视图模型协议而不是具体的类来创建视图。 2.子视图从环境中获取视图模型,而不是通过视图层次结构传递它 我已经提到了我的目标,因此,如果有完全不同的方法来实现它们,则可以公开提出建议。 当然,这是尝试过的和失败的,并引发了奇怪的错误:

struct ContentView: View {
    var body: some View {
        NavigationView {
            MyView()
        }
    }
}

struct MyView: View {
    @EnvironmentObject var viewModel: some ViewModelProtocol

    var body: some View {
        HStack {
            TextField("Enter something...", text:$viewModel.text)
            Text(viewModel.greetings)
        }
    }
}

//MARK:- View Model
protocol ViewModelProtocol: ObservableObject {
    var greetings: String { get }
    var text: String { get set }
}

class ConcreteViewModel: ViewModelProtocol {
    var greetings: String { "Hello everyone..!" }
    @Published var text = ""
}

//MARK:- Usage
let parent = ContentView().environmentObject(ConcreteViewModel())

Error

1 个答案:

答案 0 :(得分:0)

是的,但是不是很漂亮。

您遇到了问题,因为编译器无法理解如何推断some protocol应该是什么 type

some在声明您的观点时起作用的原因是,它是根据您提供给它的任何类型来推断的。

如果使视图结构采用通用的viewmodel类型,则可以进行编译。

struct MyView<ViewModel: ViewModelProtocol>: View {
    @EnvironmentObject var viewModel: ViewModel

    var body: some View {
        Text(viewModel.greetings)
    }
}

这里令人讨厌的地方是,您现在每次使用此视图时都必须声明viewmodel的 type ,如下所示:

let test: MyView<ConcreteViewModel> = MyView()