带有 ViewModel 的通用视图 SwiftUI [英] Generic View SwiftUI with ViewModel

查看:24
本文介绍了带有 ViewModel 的通用视图 SwiftUI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找具有视图和多态性的解决方案.我有一个带有特殊 ViewModel 的协议像这样:

I'm looking for a solution with View and polymorphism. I'v a a 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")
        }
    }
}

我想要一个 PQuestionView 数组:

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).

经过测试适用于 Xcode 11.2/iOS 13.2

Tested & works with Xcode 11.2 / iOS 13.2

请注意,不允许在一个容器中放置不同的类型,因此如果您打算这样做,您需要进行类型擦除,就像 SwiftUI AnyViewView.

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

这篇关于带有 ViewModel 的通用视图 SwiftUI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆