I have an SKNode which contains 2 sub nodes (a sprite node w/an image and an SKLabelNode above the image which prints the number of available units).
Previously, after each time the USER 'spent' a unit the counters would update by removing the previous unit and adding a new one.
That was working, but obviously quite inefficient. Now I'm trying to grab the existing node and update its text like so...
let newNode = createUnitCounter(type: type, nation: nation, count: countStr)
if let existingNode = iterator.filter({ $0.name == newNode.name }).first?.children.filter({ $0 is SKLabelNode }).first as? SKLabelNode {
existingNode.text = countStr
} else {
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
self.addChild(newNode)
}
}
Using breakpoints I can see that the node should be updating (it's text shows the proper values when I type po existingNode.text in the console), but the screen never shows the update. Other nodes I've refactored are updating on the screen, but not this one.
How do tell the node to redraw (e.g. something like existingNode.setNeedsDisplay())?
Here's how I create the node originally in createUnitCounter:type:nation:count ...
func createUnitCounter(type: UnitType, nation: Nation, count: String) -> SKNode {
let node = SKNode()
node.name = type.prefix + ElId.Nodes.counter
let image = createCounterImage(mode: .offense, type: type, nation: nation)
assignCounterPosition(to: image, of: type)
node.addChild(image)
let label = createCounterLabel(text: count, position: nil, type: type)
label.verticalAlignmentMode = .bottom
assignCounterPosition(to: label, of: type)
node.addChild(label)
return node
}
func createCounterLabel(text: String, position: CGPoint?, type: UnitType?) -> SKLabelNode {
let node = SKLabelNode(fontNamed: Assets.font)
node.text = text
node.zPosition = Position.zUIElementH
if type == selectedUnitType { node.fontColor = Colors.red }
if let p = position { node.position = p }
return node
}
func createCounterImage(mode: GameMode, type: UnitType = .infantry, nation: Nation = .usa) -> SKSpriteNode {
...
}
So I isolated the issue to the fact that it was chaining the filters through an iterator which broke the node's reference. When I switched the iterator back out to the children array, everything was working. However that was going to create issues, so I found a similar method and for some reason I was able to keep the iterator and the references survived when accessing the same node independent of the iterator and then accessing that...