简体   繁体   English

带有 ViewModel 的通用视图 SwiftUI

[英]Generic View SwiftUI with ViewModel

I'm looking for a solution with View and polymorphism.我正在寻找具有视图和多态性的解决方案。 I'v aa protocol with a special ViewModel like that:我有一个像这样的特殊 ViewModel 的协议:

protocol PQuestionView: View {
    associatedtype VM where VM : BaseQuestionViewModel
    var vm: Self.VM { get }
}

so I can use it in a struct like that:所以我可以在这样的结构中使用它:

struct test: PQuestionView {
    var vm:YesNoQuestionViewModel = YesNoQuestionViewModel(question: Question(), temporaryId: 3)
    var body: some View{
        VStack{
            Text("Yes")
        }
    }
}

I want to have an array of PQuestionView:我想要一个 PQuestionView 数组:

var questionViews: [PQuestionView]

But I have two associated types, it seems that way of implementing view doesn't work as polymorphism.但是我有两个相关的类型,似乎实现视图的方式不像多态那样工作。 So I tried something like that:所以我尝试了这样的事情:

struct StrongView<MyView: View,VM: BaseQuestionViewModel> : PQuestionView{
    var vm: VM
    var body: MyView
}

But it's have a strongly typed struct and it doesn't answer to my genericity problem... Does a good solution exists to that job?但它有一个强类型的结构,它不能解决我的通用性问题......该工作是否存在一个好的解决方案?

Here is how it could be used (due to absent all types I replicate those with simple stub).这是它的使用方法(由于缺少所有类型,我用简单的存根复制了那些类型)。

Tested & works with Xcode 11.2 / iOS 13.2经测试适用于 Xcode 11.2 / iOS 13.2

Please note, it is not allowed to place different types in one container, so if you intended to do this you'll need type erasure, like SwiftUI AnyView do for View .请注意,这是不允许放置不同类型的一个容器,所以如果你打算这样做,你需要键入擦除,像SwiftUI AnyView为做View

protocol BaseQuestionViewModel {
}

struct YesNoQuestionViewModel: BaseQuestionViewModel {
}

protocol PQuestionView: View {
    associatedtype VM where VM : BaseQuestionViewModel
    var vm: Self.VM { get }
}

struct test: PQuestionView {
    var vm = YesNoQuestionViewModel()
    var body: some View{
        VStack{
            Text("Yes")
        }
    }
}

struct QuestionsHolder<T: PQuestionView>: View {
    var questionViews: [T]
    var body: some View {
        ForEach(0..<questionViews.count) { i in
            self.questionViews[i]
        }
    }
}

struct TestViewGenerics_Previews: PreviewProvider {
    static var previews: some View {
        List {
            QuestionsHolder(questionViews: [test(), test(), test()])
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM