I’m working on an iOS app in SwiftUI where I have a shared ObservableObject that I want to pass between multiple views. The object is meant to keep track of some shared app state, like user settings or session data.
In one of my views, I use @StateObject to create an instance of this object. However, I noticed that any changes I make to the ObservableObject in another view cause my original view to update unexpectedly. It’s as if the object is being observed in multiple places, even though I thought @StateObject would keep it isolated in the view where it’s declared.
Here’s a simplified version of my code:
import SwiftUI
class SharedData: ObservableObject {
@Published var counter: Int = 0
}
struct ParentView: View {
var body: some View {
VStack {
CounterView()
AnotherView()
}
}
}
struct CounterView: View {
@StateObject private var data = SharedData()
var body: some View {
VStack {
Text("Counter: \(data.counter)")
Button("Increment Counter") {
data.counter += 1
}
}
}
}
struct AnotherView: View {
@ObservedObject var data = SharedData() // <- Issue?
var body: some View {
Text("Another View Counter: \(data.counter)")
}
}
When I increment the counter in CounterView, AnotherView also reflects the changes in data.counter. I don’t understand why AnotherView is updating when CounterView increments data.counter, as I thought each view would manage its own instance.
@ObservedObject var data = SharedData()inAnotherView. Did you mean to write@StateObject var data = SharedData()instead (same as inCounterView)?@StateObjectwould be for when I want a view to "own" an instance of anObservableObject, while@ObservedObjectwould allow a view to observe changes without creating a new instance. My intention with AnotherView was to simply observe any changes made inCounterView, but it seems that creating a new instance ofSharedDatainAnotherViewis what's causing the unexpected updates. Would passing theSharedDatainstance fromParentViewand using@ObservedObjectin bothCounterViewandAnotherViewwork better in this scenario?