Understand how SpriteKit layers your scene's nodes from top to bottom.
The standard behavior for scene rendering follows a simple pair of rules (as shown in Figure 1):
A parent draws its content before rendering its children.
Children are rendered in the order in which they appear in the child array.
In the figure above, the helicopter body and its components are all children of the
sky node. So the scene renders its content as follows:
The scene renders itself, clearing its contents to its background color.
The scene renders the
skynode renders its children—the helicopter body and its components—in the order they were added as children.
Draw Order Relative to the Parent Node
Maintaining the order of a node’s children can be a lot of work. Instead, you can give each node an explicit height in the scene. You do this by setting a node’s
z property. The
z is the node’s height relative to its parent node, much as a node’s
position property represents its x and y position relative to its parent’s position. So you use
z to place a node above or below the parent’s position.
When you take
z into account, here is how the node tree is rendered:
Each node’s global
zis calculated by recursively adding its
zto its parent's
Nodes are drawn in order from smallest
If two nodes share the same
z, ancestors are rendered first, and siblings are rendered in child order.
Sibling Order Performance
SpriteKit uses a deterministic rendering order based on the height nodes and their positions in the node tree. But, because the rendering order is so deterministic, SpriteKit may be unable to apply some rendering optimizations that it might otherwise apply. For example, it might be better if SpriteKit could gather all of the nodes that share the same texture and drawing mode and draw them with a single drawing pass. To enable these sorts of optimizations, you set the view’s
ignores property to
When you ignore sibling order, SpriteKit uses the graphics hardware to render the nodes so that they appear sorted by
z. It sorts nodes into a drawing order that reduces the number of draw calls needed to render the scene. But with this optimized drawing order, you cannot predict the rendering order for nodes that share the same height. The rendering order may change each time a new frame is rendered. In many cases, the drawing order of these nodes is not important. For example, if the nodes are at the same height but do not overlap on screen, they can be drawn in any order.
Figure 2 shows an example of a tree that uses
z to determine the rendering order. In this example, the body of the helicopter is at a height of 100, and its children are rendered relative to its height. The two rotor nodes share the same height but do not overlap.
Interleaved Child Nodes from Different Parents
Because a child node's
z is added to its parent's
z, you can interleave child nodes from different parent nodes. Listing 1 shows code that creates two square parent nodes, each with a circular child node. The first node has a
z of 10 and its child node has a
z of 10. The second node has a
z of 15 and its child node also has a
z of 10.
Once added to the scene, the child of the first node has an effective global
z of 20 and the child of the second node has an effective global
z of 25, giving an interleaving effect.
Figure 3 shows the resulting scene.
z is additive across parent-child node relationships, you can use both tree order and
z to determine your scene’s rendering order. When rendering a complex scene, you should disable the sorting behavior and use the
z of nodes to create a deterministic scene order.