Generi c View SwiftUI с ViewModel - PullRequest
       3

Generi c View SwiftUI с ViewModel

1 голос
/ 10 февраля 2020

Я ищу решение с View и полиморфизмом. У меня есть протокол со специальной ViewModel, такой как:

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

, поэтому я могу использовать его в такой структуре:

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

Я хочу иметь массив PQuestionView:

var questionViews: [PQuestionView]

Но у меня есть два связанных типа, кажется, что способ реализации представления не работает как полиморфизм. Поэтому я попробовал что-то вроде этого:

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

Но у него есть строго типизированная структура, и она не отвечает на мою проблему универсальности ... Есть ли хорошее решение для этой работы?

1 Ответ

1 голос
/ 10 февраля 2020

Вот как это можно использовать (из-за отсутствия всех типов я копирую их с простой заглушкой).

Протестировано и работает с Xcode 11.2 / iOS 13.2

Обратите внимание, что нельзя помещать разные типы в один контейнер, поэтому, если вы намеревались это сделать, вам понадобится тип стирание, как SwiftUI AnyView do для 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()])
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...