Я пытаюсь использовать MVVM в приложении SwiftUI, однако кажется, что модели представлений для дочерних представлений (например, в NavigationLink
) переинициализируются всякий раз, когда ObservableObject
наблюдается как родительским, так и дочерним. обновляется. Это приводит к сбросу локального состояния ребенка, перезагрузке сетевых данных и т. Д. c.
Я предполагаю, что это потому, что это вызывает переоценку родительского body
, который содержит конструктор для * 1006. * модель представления, но я не смог найти альтернативу, которая позволила бы мне создавать модели представления, которые не живут за пределами срока действия представления. Мне нужно иметь возможность передавать данные в дочернюю модель представления от родителя.
Вот очень упрощенная площадка для того, что мы пытаемся выполнить sh, где увеличение EnvCounter.counter
сбрасывает SubView.counter
.
import SwiftUI
import PlaygroundSupport
class EnvCounter: ObservableObject {
@Published var counter = 0
}
struct ContentView: View {
@ObservedObject var envCounter = EnvCounter()
var body: some View {
VStack {
Text("Parent view")
Button(action: { self.envCounter.counter += 1 }) {
Text("EnvCounter is at \(self.envCounter.counter)")
}
.padding(.bottom, 40)
SubView(viewModel: .init())
}
.environmentObject(envCounter)
}
}
struct SubView: View {
class ViewModel: ObservableObject {
@Published var counter = 0
}
@EnvironmentObject var envCounter: EnvCounter
@ObservedObject var viewModel: ViewModel
var body: some View {
VStack {
Text("Sub view")
Button(action: { self.viewModel.counter += 1 }) {
Text("SubView counter is at \(self.viewModel.counter)")
}
Button(action: { self.envCounter.counter += 1 }) {
Text("EnvCounter is at \(self.envCounter.counter)")
}
}
}
}
PlaygroundPage.current.setLiveView(ContentView())