简体   繁体   中英

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:

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:

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

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 .

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()])
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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