3

We want to iterate through the ancestors of a node until we find a parent with a specific class.

SpriteKit lets you iterate through children with the children property, but the parent property only holds the immediate parent -- not an array of parents. How do we iterate through all the ancestors of a node?

Crashalot
  • 33,605
  • 61
  • 269
  • 439
  • I am pretty sure using childNodeWithName gets you nodes in both directions, you just need to use `/` to have it start at the root node, doesn't exactly get you the parent, but it may help if child knows grandpa's name – Knight0fDragon Apr 18 '17 at 13:25
  • @Knight0fDragon interesting idea. why not post as an answer so more people see it? if you have tried this and know it works, i can mark it as the answer. – Crashalot Apr 18 '17 at 20:43
  • Not an answer to your question, it is more of a different strategy – Knight0fDragon Apr 18 '17 at 21:13

2 Answers2

5

I'm not aware of a function that lets you go up the hierarchy, similar like the enumerateChildNodes function allows you to go down the hierarchy. Maybe this recursive function may help. Below I've set recursion to end when there is no parent, or when the parent is an SKScene class. You may need to adjust it so that recursion ends when your particular class is found.

func parentNodesOf(_ node: SKNode) -> [SKNode]
{
    if let parentNode = node.parent
    {
        if parentNode is SKScene
        {
            return []
        }
        else
        {
            return [parentNode] + parentNodesOf(parentNode)
        }
    }
    else
    {
        return []
    }
}

Hope this helps!

JohnV
  • 981
  • 2
  • 8
  • 18
  • 2
    Maybe this could be even more useful if put in an extension of the `SKNode` class (say, parents property). – Whirlwind Apr 18 '17 at 09:50
  • True. You probably want this to be in an extension of SKNode, rather than a loose standing function. – JohnV Apr 18 '17 at 10:55
0

An alternative to JohnV's answer

extension SKNode {
    func forEachAncestor(_ closure: (_ ancestor: SKNode) -> Void) {
        var currentParent: SKNode? = self.parent
        while currentParent != nil {
            closure(currentParent!)
            currentParent = currentParent!.parent
        }
    }
}