Converting Between Coordinate Systems in SpriteKit

When adding a new node to a scene in SpriteKit, the node may have a number of child nodes. For example, when making a button, the parent node might be an SKShapeNode, to make a square. The children might include an SKLabelNode (the text label on the button, e.g., "submit"), and a transparent SKSpriteNode. I usually put a transparent SKSpriteNode at the highest zPosition with a unique name on a button. That way, when the button is touched, the transparent layer is detected and not the SKLabelNode underneath by accident.

When adding the child nodes to the parent, they take on a coordinate system that is relative to the parent. For example, I might add a button's parent node to the center of the scene (x: ((view?.bounds.width)! / 2), y: ((view?.bounds.height)! / 2)). When a touch is detected on a button's transparent layer, the coordinates that are passed are not the center coordinates of the screen. Instead, they coordinates are (x: 0, y: 0) -- the child's coordinates relative to the parent!

This rule in SpriteKit has its benefits, as children are ensured to follow their parent node. However, there are times where you want to get the coordinates of an SKNode's layer relative to the scene. To convert between the child node's and scene's coordinate spaces, you can use the convert method.

For example, node is the variable used when a node is touched in the scene. To get the node's position relative the scene, you could read its scene coordinates as:

let convertedPosition = node.scene?.convert(node.position, from node.parent!)

Of course, that assumes that node has a parent! A safe way to do the conversion is:

if let nodeParent = node.parent {
    convertedPosition = node.scene?.convert(node.position, from node.parent!)
}
else {
    convertedPosition = nil
}

That way, if (for some reason) node doesn't have a parent, an error won't be thrown. Providing everything goes correctly, convertedPosition will now store the node's coordinates as they are in the scene.

You can read more in Apple's API reference for SKNode.