iOS Swift如何使用For循环SKAction的完成处理程序

时间:2018-06-12 16:23:34

标签: for-loop swift3 sprite-kit skaction completionhandler

我想创建并运行一些SKAction。在SKAction之后,程序将打印一条消息。

let actLoop = SKAction.run {
for i in 1 ... 10 {

    self.stone[i - 1].position = CGPoint(x: 0 , y: -100)
    self.stone[i - 1].anchorPoint = CGPoint(x: 0.5, y: 0.5)
    self.stone[i - 1].size = CGSize(width: 50, height: 50)
    self.addChild(self.stone[i - 1])   

    let actionMove = SKAction.move(to: CGPoint(x: 0, y: 0), duration: 0.3)
    let actionRolling = SKAction.animate(with: stone[i - 1].arrayTexture, timePerFrame: 0.05)
    let actionSequence = SKAction.sequence([actionMove,actionRolling])
    stone[i - 1].run(actionSequence)
}

self.run(actLoop) {

print("Completed")

}

程序最后不会打印“已完成”消息,但消息将在SKActions执行的同一时间出现。我希望只有在所有SKActions完成后才会显示该消息。我也试过这个:

    self.run(actLoop, completion: {
        //
        print("Completed")

        })

这也行不通。我似乎无法做到这一点。

2 个答案:

答案 0 :(得分:0)

我试着在另一个问题上向你解释这个问题。 for循环在进入下一个项目之前不要等待操作完成。 for循环即时(几乎)处理所有10个项目。因此,您正在经历的输出是预期的。有许多方法可以做到这一点,但有些方法比其他方法更复杂(即完成块)。最简单的方法就是跟踪for循环中的持续时间并等待该持续时间触发完成。

根据您在此处提供的代码,所有10个项目同时显示在屏幕上,这与您在此主题上提出的最后一个问题相矛盾。

for x in 0..<10 {
    self.run(.wait(forDuration: 1.0)) {
        print(x)
    }
}
在代码运行后1秒,

将在单独的行上打印出0,1,2,3,4,5,6,7,8,9,因为循环中的所有行都是在一次,然后告诉等待1秒钟再打印。

var delay: double = 1.0
for x in 0..<10 {
    self.run(.wait(forDuration: delay)) {
        print(x)
    }

    delay += 1
}

将打印出0,1,2,3,4,5,6,7,8,9在单独的行上1秒后,在前一个打印后,最后一个总计10秒,输出代码运行,因为循环中的那些行被一次处理并被告知在打印之前等待更长的持续时间。

var delay: double = 1.0
for x in 0..<10 {
    self.run(.wait(forDuration: delay)) {
        print(x)
    }

    delay += 1
}

self.run(.wait(forDuration: delay)) {
    print("all done adding objects")
}

这将在最后一行完成之后输出最后一行,因为我们已经等待了必要的时间。

答案 1 :(得分:0)

立即激活块并在块完成时完成,而不是在块内的所有操作完成时完成。

即使您要在for循环中依次链接您的操作,您的运行块也会在更新周期结束时完成。

如果你计划逐个解雇你的代码,然后有一个完成块,我建议你把所有的动作都放到一个序列动作中。