In an ongoing quest to pass data from a SpriteKit scene to a SwiftUI view, I have discovered the following mystery (to me, at least). I hope the solution might break the impasse. I have a ContentView which uses SpriteView() to contain/display a SpriteKit scene called GameScene. I have a class called Counter(), which is subclassed as an ObservableObject. (Note the print statement in the body of the add(count) func.)
import SwiftUI
class Counter: ObservableObject {
@Published var count : Int = 0
func add(count: Int) {
self.count += count
print("Add \(count); new total: \(self.count)")
}
}
In ContentView, for the purpose of testing and comparison, I have added a button which calls the add(count) func:
import SwiftUI
import SpriteKit
struct ContentView: View {
@ObservedObject var counter = Counter()
var scene: SKScene {
let scene = GameScene()
scene.size = CGSize(width: 300, height: 400)
scene.scaleMode = .fill
return scene
}
var body: some View {
VStack{
SpriteView(scene: scene)
.frame(width: 300, height: 400)
.ignoresSafeArea()
Button{
counter.add(count: 1)
} label: {
Text("Add to count")
}
Text("New count = \(counter.count)")
}
}
}
When the button (in ContentView) is tapped, the count increments and is displayed immediately as expected.
In GameScene I have virtually the same call to the add(count) func, but it fails (refuses?) to update the ContentView.
class GameScene: SKScene {
var counter = Counter()
var count = 0
...
//a SpriteKitNode called "button" is created then added in didMove(toView)//
...
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else { return }
let location = touch.location(in: self)
if button.contains(location) {
counter.add(count: 1)
}
}
}
The print statement reads the same whether the call comes from GameScene or ContentView. With the first tap of either button it reads:
Add 1; new total: 1
Add 1; new total: 2
Add 1; new total: 3 , and so on.
In other words, up until the call to the func that is meant to update the published var, they seem to behave identically. But...
The Mystery:
Why does the call from ContentView trigger the desired update while the same call from GameScene does not?
I look forward to having the scales removed from my weary eyes!