Я пытаюсь правильно реализовать MVVM в SwiftUI, поэтому я придумал эту (упрощенную) модель и ViewModel:
struct Model {
var property1: String
var property2: String
}
class ViewModel: ObservableObject {
@Published var model = Model(property1: "this is", property2: "a test")
}
Использование этого в View
работает нормально, но я испытал некоторые из-за проблем с производительностью, поскольку я расширил ViewModel
некоторыми вычисленными свойствами и некоторыми функциями (а сам Model
более сложен). Но давайте остановимся на этом примере, потому что он отлично демонстрирует, что я считаю большой проблемой в самом SwiftUI.
Представьте, у вас есть эти представления для отображения данных:
struct ParentView: View {
@ObservedObject var viewModel: ViewModel
var body: some View {
print("redrawing ParentView")
return ChildView(viewModel: self.viewModel)
}
}
struct ChildView: View {
@ObservedObject var viewModel: ViewModel
var body: some View {
print("redrawing ChildView")
return VStack {
ViewForTextField(property: self.$viewModel.model.property1)
ViewForTextField(property: self.$viewModel.model.property2)
}
}
}
struct ViewForTextField: View {
@Binding var property: String
var body: some View {
print("redrawing textView of \(self.property)")
return TextField("...", text: self.$property)
.textFieldStyle(RoundedBorderTextFieldStyle())
}
}
Теперь ввод текста в один из TextField
приводит к перерисовке каждые View
в моем окне! Вывод на печать:
redrawing ParentView
redrawing ChildView
redrawing textView of this is
redrawing textView of a test
redrawing ParentView
redrawing ChildView
redrawing textView of this isa
redrawing textView of a test
redrawing ParentView
redrawing ChildView
redrawing textView of this isab
redrawing textView of a test
...
Как я вижу, SwiftUI redr aws каждый вид, потому что каждый вид слушает ObservedObject
.
Как я могу сказать SwiftUI, что он должен перерисовывать только те представления, где действительно произошли какие-либо изменения?