3
votes

Is there a way to hook into the SKNode lifecycle in Sprite Kit? Specifically I would like to perform some code when the node gets removed from the scene.

The use case I would like to solve in a bit more detail : I have some nodes that interact with each other, and I would like them to be notified of certain events that happen to the other nodes. For example, imagine a game where you can tap a node on the scene, and the node's details would appear on a HUD. I would like the HUD to disappear when the node gets removed from the scene. I plan to use NSNotificationCenter as the notification engine. Whenever a node gets removed from the scene I would like to post a notification. The easiest way would be to tie into a lifecycle method on SKNode (my nodes are subclasses of SKSpriteNode) like nodeWasRemovedFromParent, but I didn't find any such method.

How can this be done?

I put some thought into coding my own solution by overriding the removeFromParent method in my SKSpriteNode subclass, and posting a notification before calling the super implementation. I am not sure that the removeFromParent method will always be called though. For example, does it get called when I change scenes?

Thanks.

1

1 Answers

4
votes

You need to subclass each node class. Override the removeFromParent method as you said. Use only the subclassed versions, otherwise your code won't take effect.

In addition you will want to override removeAllChildren and removeChildrenInArray: or just never use them.

The removeFromParent method will not be called when the scene changes. Instead, override the scene's willMoveFromView: method and send a message to registered observers or simply all child nodes recursively. Use the scene's enumeration function to do so. Note that I'm not 100% sure whether on willMoveFromView the scene's children are still attached, I assume they will.

Unfortunately it's impossible to just subclass SKNode and then expect the subclass' code to work for all other node classes, because those subclass from SKNode directly and not your custom SKNode subclass. Hence you need to subclass and add this code to every SK*Node subclass as well if you need it to be notified on removal.

See KoboldKit node classes for an example, which uses a macro to inject this "override" code into SK*Node subclasses to avoid duplicating the code. The actual functionality is in KKNodeShared: https://github.com/KoboldKit/KoboldKit/tree/master/KoboldKit/KoboldKitFree/Framework/Nodes/Framework