I recently encountered the following problem in SwiftUI
with ObservedObject
/ObservableObject
:
If the ObservedObject
/ObservableObject
is publishing in a View, the body
property is recalculated - as expected.
But if there is a sub View in the body
property which also has an ObservedObject
, the View, strangely enough, not only recalculates the body
property of the sub View, but the entire object
.
The state of the ObservedObject
is of course lost from the sub View.
Of course, you can prevent this by adding the ObservableObject
to the sub View through .environmentObject()
, but I don't think that's the best solution, especially with more complex view hierarchies.
Here an example Code:
struct ContentView: View {
@ObservedObject var contentViewModel: ContentViewModel = ContentViewModel()
var body: some View {
VStack {
Button {
self.contentViewModel.counter += 1
} label: {
Text(String(self.contentViewModel.counter))
}
SubView()
}
}
}
class ContentViewModel: ObservableObject {
@Published var counter: Int = 0
}
And the sub View:
struct SubView: View {
@ObservedObject var subViewModel: SubViewModel = SubViewModel()
var body: some View {
Button {
self.subViewModel.counter += 1
} label: {
Text(String(self.subViewModel.counter))
}
}
}
class SubViewModel: ObservableObject {
@Published var counter: Int = 0
}
And here how the sample Code looks/works:
The last weird thing I realised, this is only the case if you use Observed Object. If I would replace in the sub View @ObservedObject var subViewModel: SubViewModel = SubViewModel()
with @State var counter: Int = 0
it is working fine again and the state is preserved.
Maybe im missing out on something, but im really confused. Im very grateful for any answers and solutions. If you have further questions fell free to leave a comment, I will answer it within 24h (as long as the question is open).