I have an ObservableObject called DataSource shared among some views. Each view has a button that changes a state variable to switch to the next view. In View2, I am trying to update some data in DataSource when button is pressed, which should be done right before it switches to the next view.
However when the button in View2 is pressed, even though the view is already switched to View3, View2 is also being redrawn in the background, and code in View2 body was executed again in the background (See output below, the list was printed twice), which is not what I want here.
Is there a way to modify the ObservableObject in the current view (e.g., when pressing the button in current view) without redrawing the current view (or rerunning code in current view body)? E.g., when the button is pressed the current view should update the ObservableObject without redrawing or executing the code in the current view body again.
class DataSource: ObservableObject {
static let shared=DataSource()
@Published var listOfThings:[String] = ["qwe"]
}
struct View2: View {
@Binding var views:String
@ObservedObject var dataSource = DataSource.shared
var body: some View {
let _ = print("Loading View2: ",dataSource.listOfThings)
//let text = dataSource.listOfThings[0] //Throws ERROR when redraw in background: index out of range
Text(text)
Button("Next view"){
dataSource.listOfThings.popLast()
// There are other lines of code updating dataSource here
views="c"
}
}
}
struct View3: View {
@Binding var views:String
@ObservedObject var dataSource = DataSource.shared
var body: some View {
Text(dataSource.listOfThings.joined())
}
}
struct ContentView: View {
@State var views = "b"
var body: some View {
switch views {
case "b":
View2(views: $views)
case "c":
View3(views: $views)
default:
Text("Not handled view type")
}
}
}
Output when reaching View3:
Loading View2: ["qwe"]
Loading View2: [] //Ideally this should not be printed