I can't get an @StateObject variable correctly initialized within the main view init() routine. It looks as if the object gets reinitialized at every modification and ends up being unpopulated when the ui gets ready. Here is the code:
import SwiftUI
class Node: Identifiable {
var id = UUID()
var x = 0.0
var y = 0.0
func toString() -> String {
return "\(id):(\(x), \(y))"
}
}
class Objects: ObservableObject {
@Published var nodes: [Node] = []
@Published var show: Bool = false
func addNode(_ node: Node) {
self.nodes.append(node)
print(self.nodes.count)
}
func toString() -> String {
var s = "Nodes: (\(self.nodes.count))\n"
for node in self.nodes {
s += node.toString() + "\n"
}
return s
}
}
struct ContentView: View {
@StateObject var objects = Objects()
init() {
var node = Node()
node.x = 50
node.y = 200
print(node.toString())
objects.addNode(node)
node = Node()
node.x = 200
node.y = 100
print(node.toString())
objects.addNode(node)
objects.show.toggle()
print(objects.toString())
}
var body: some View {
Button("Add") {
let i = objects.nodes.count
let node = Node()
node.x = Double(i)
node.y = Double(i)
objects.addNode(node)
print(objects.toString())
}
.padding()
.foregroundColor(.white)
.background(.red)
}
}
The console unexpectedly shows me this:
31042C43-103A-48F3-B926-47A5B2CB9610:(50.0, 200.0)
1
6B95D75C-8849-4840-AB0F-56BEED00D73F:(200.0, 100.0)
1
Nodes: (0)
Now, pressing the "Add" button, the array count increases starting from 1.
If I change the declaration of the variable from
@StateObject var objects = Objects()
to
@State var objects = Objects()
the initialization goes as expected:
6A2A5EFF-1A7F-4995-B2D6-DC22537FB4D1:(50.0, 200.0)
1
A118917D-6635-4E4E-AED0-B865AF2DA81C:(200.0, 100.0)
2
Nodes: (2)
6A2A5EFF-1A7F-4995-B2D6-DC22537FB4D1:(50.0, 200.0)
A118917D-6635-4E4E-AED0-B865AF2DA81C:(200.0, 100.0)
and the array count starts from 3 when I press the “Add” button.
Unfortunately, I need to share the object across views and the @StateObject is necessary. Can you suggest a solution and explain to me why this appens?