@State
и @Binding
так хорошо работают в SwiftUI
, если вы помещаете все данные представления в себя, например:
struct ColorView: View {
@Binding public var isBlue: Bool
var body: some View {
Rectangle()
.foregroundColor(isBlue ? .blue : .red)
.onTapGesture {
self.isBlue.toggle()
}
}
}
struct TestView: View {
@State var isBlue: Bool = false
var body: some View {
ColorView(isBlue: $isBlue)
}
}
Это работает без проблем, и это действительно просто. Но MVVM
говорит, что вы должны поместить все данные представления в класс модели представления, чтобы отделить пользовательский интерфейс от модели. Но тогда вы теряете @State
и @Binding
полностью. Вы теряете это двустороннее связывание, кажется. Конечно, вы можете сделать это вручную с помощью Combine
или чего-то еще, но это не должно быть правильным способом, верно?
Всякий раз, когда я что-то пробую, SwiftUI
действительно легко и удобно, когда вы не используете модели представлений. Как только вы помещаете все в класс модели представления, все разрушается, и больше ничего не работает. Этого не может быть, они должны были подумать об этом. Так что я что-то здесь упускаю. Буду очень признателен за любую помощь. Как бы вы кодировали приведенный выше пример, используя модели представления (без «взлома» чего-либо вручную)? Я пытался, но он даже не компилируется:
struct ColorView: View {
@ObservedObject var viewModel: ViewModel
class ViewModel: ObservableObject {
// Binding or Published? Both doesn't seem to work
@Binding var isBlue: Bool
init(isBlue: Binding<Bool>) { // Or type Bool? But then we lose the binding
self.$isBlue = isBlue
}
}
var body: some View {
Rectangle()
.foregroundColor(viewModel.isBlue ? .blue : .red)
.onTapGesture {
self.viewModel.isBlue.toggle()
}
}
}
struct TestView: View {
@ObservedObject var viewModel: ViewModel
class ViewModel: ObservableObject {
@Published var isBlue: Bool = false // We would need a @State here, but then we lose @Published
}
var body: some View {
ColorView(viewModel: .init(isBlue: /* ??? */)) // How to pass a binding here`
}
}
Думаю ли я об этом неправильно?
Спасибо!