SpriteKit Animations: Moving multiple nodes to different positions in a loop

After having researched SpriteKit implementations and QAs, I felt it was better for me to ask the question myself. I'm trying to create a Dance Formations App where there is an option to play through all formations created. I'm Using SKAction to move each of the nodes in the formation. For example, the code loops through an array of formations, for formation 1: the 3 dancers move to their respective positions, for formation 2, the 3 dancers move to their next respective positions together, and so on.

The problem is that as I go through the for loop - each of the nodes move position is being updated asynchronously, so the dancers never go from Formation 1 -> 2 -> 3, they end up going from Formation 1 -> Last formation positions. Please help!


let action =  SKAction.run{
//Calculating formationArray to get next Formation done here

for dancer in formationArray {
           
if let toUpdateIndex = currNodes.firstIndex(where: { $0.nodeId == dancer.id }) {
                let next = CGPoint(x: CGFloat(dancer.xPos), y: CGFloat(dancer.yPos))
                let action = SKAction.move(to: next , duration: 3.0)

                currNodes[toUpdateIndex].run(action)
////In the above line, each node is receiving it's own position to move to
        }
}

let sequence = SKAction.sequence([action, action, action])
self.run(sequence)
If you want to run some actions sequentially, you may need to create a sequence of actions as in let sequence = ....
(Please use Code block (< >) shown below the editing box.)

Or you need to run the next action when the current action is completed.
You may need to use run(_:completion:) instead of run(_:).
(It is very hard to show detailed code as you are not showing enough info.)
Here is more detailed code :). I also tried using run(_:completion:) and the same thing happens - the run does not wait for the action to complete before running the completion code.

Code Block
let actionA = SKAction.run { [unowned self] in
            var currNodes: [DanceNode] = []
                self.enumerateChildNodes(withName: "draggable") { (node, stop) in
                currNodes.append(node as! DanceNode)
            }
                self.formationVM.formationArray = self.formationVM.loadFormations()
                if let nextFormation = self.formationVM.getNextFormation(){
                    let nextDancerForms = self.dancerVM.loadNextDancers(nextFormation: nextFormation)
        for dancer in nextDancerForms{
            if let toUpdateIndex = currNodes.firstIndex(where: { $0.nodeId == dancer.id }) {
                let next = CGPoint(x: CGFloat(dancer.xPos), y: CGFloat(dancer.yPos))
                let action = SKAction.move(to: next , duration: 1.0)
                currNodes[toUpdateIndex].run(action)
  }
        }
                    self.formationVM.currentIndex += 1
    }
        }
            let sequence = SKAction.sequence([actionA, actionA, actionA, actionA])
            self.run(sequence)
}

Here is more detailed code :).

Thanks for showing your code. And sorry, I was not clear enough.
What is making things difficult is lacking the definition of formationArray or currNodes (DanceNode).
And where these lines exist? In a method of GameScene (or any subclass of SKScene)? Or in some other place, for example a subclass of SKSpriteNode?


I also tried using run(_:completion:) and the same thing happens 

You may have called run(_:completion:) repeatedly in the loop. You need to call the next run(_:completion:) in the completion: of previous run. To show how to achieve that, I need more info as described above.
I figured it out! The problem was that I was not waiting before executing the next action.
SpriteKit Animations: Moving multiple nodes to different positions in a loop
 
 
Q