space 三个动画间隔一秒的最佳方法是什么?

What is the best way to space three animations one second apart?

有没有比使用 asyncAfter 三次更好的方法让这些动画间隔一秒?

let firstAnimationTime = DispatchTime.now()
let secondAnimationTime = DispatchTime.now() + 1
let thirdAnimationTime = DispatchTime.now() + 2
DispatchQueue.main.asyncAfter(deadline: firstAnimationTime) {
    self.firstAnimation()
}
DispatchQueue.main.asyncAfter(deadline: secondAnimationTime) {
    self.secondAnimation()
}
DispatchQueue.main.asyncAfter(deadline: thirdAnimationTime) {
    self.thirdAnimation()
}

你可以像这样嵌套/延迟

UIView.animate(withDuration: 0.25, delay: 0.0, options: [], animations: {
      // first animation
}, completion: { (finished: Bool) in

          UIView.animate(withDuration: 0.25, delay: 0.0, options: [], animations: {
            // second animation
          }, completion: { (finished: Bool) in


         })
})

您可以根据自己的情况创建任何您想要的工具,但从您所描述的内容来看,您拥有的工具似乎已经很完美了。这样看;完美的情况是:

ToolName.performAt(time, { execution })

所以在你的情况下 ToolName 可以替换为 let queue = DispatchQueue.main 就完成了。

但你当然可以这样做:

    typealias ExecutionClosureType = () -> Void

    func executeInIntervals(intervalDuration: TimeInterval, toExecute closureArray: [ExecutionClosureType]) {
        let now = DispatchTime.now()
        let queue = DispatchQueue.main
        closureArray.enumerated().forEach { (index, closure) in
            queue.asyncAfter(deadline: now + intervalDuration*TimeInterval(index), execute: closure)
        }
    }

然后使用:

    executeInIntervals(intervalDuration: 1.0, toExecute: [
        {
            self.firstAnimation()
        }, 
        {
            self.secondAnimation()
        },
        {
            self.thirdAnimation()
        }
    ])

如果需要这个工具,你应该这样做。

您可以使用 UIView.animate(withDuration:delay:...)

甚至可以定义一个函数如下:

func animateSequentially(withDurations durations: [TimeInterval], animations: [(() -> Void)]) {

    guard durations.count == animations.count else {
        return
    }

    for index in 0..<animations.count {

        // calculate delay
        let delay: TimeInterval = durations[0..<index].reduce(TimeInterval(0), { delay, duration in
            return delay + duration
        })

        // perform animation
        UIView.animate(withDuration: durations[index],
                       delay: delay,
                       options: [],
                       animations: animations[index],
                       completion: nil)
    }
}

并像这样使用:

let myView = UIView()

let durations = [1, 0.5, 1.25]

let animations = [{ myView.backgroundColor = .red },
                  { myView.backgroundColor = .yellow },
                  { myView.backgroundColor = .blue }]

animateSequentially(withDurations: durations, animations: animations)