For In Loop 动画在数组包含重复项时被跳过

For In Loop animations being skipped when the array contains duplicates

我有一个函数可以遍历 UIButtons 数组并为数组中的每个按钮一个接一个地设置动画。目前这一切都完美无缺,直到一个按钮不止一次附加到数组然后它跳过两个实例的动画。有没有办法阻止这种行为?

func animateButtons() {
        disableButtons()

        for (index, button) in buttonSequence.enumerated() {
            group.enter()
            UIButton.animate(
                withDuration: 1,
                delay: TimeInterval(index),
                animations: {
                    button.backgroundColor = UIColor(red: 63/255, green: 255/255, blue: 0/255, alpha: 1.0)
                },
                completion: { finished in
                    button.backgroundColor = UIColor(red: 168/255, green: 61/255, blue: 164/255, alpha: 0.85)
                    self.group.leave()
                }
            )
        }

        group.notify(queue: .main) {
            self.enableButtons()
        }
    }

问题是你的带有人工 delay 参数的 for 循环是完全错误的。链接动画的方法是使用关键帧动画或使用递归。在这种情况下,我会建议递归。这是一个简单的工作示例;这是 完整 代码,用于带有两个按钮的应用程序以及一些触发 start 功能的方法,所以请自己尝试一下:

func delay(_ delay:Double, closure:@escaping ()->()) {
    let when = DispatchTime.now() + delay
    DispatchQueue.main.asyncAfter(deadline: when, execute: closure)
}
class ViewController: UIViewController {
    @IBOutlet weak var button1: UIButton!
    @IBOutlet weak var button2: UIButton!
    func start() {
        // starting, disable buttons
        let buttonSequence : [UIButton] = [ button1, button2, button1, button1, button2 ]
        self.animate(buttonSequence)
    }
    func animate(_ seq:[UIButton]) {
        if let b = seq.first {
            UIView.animate(withDuration: 1, delay: 0, options: [], animations: {
                b.backgroundColor = .red
            }) { _ in
                b.backgroundColor = nil
                delay(0.1) {
                    self.animate(Array(seq.dropFirst()))
                }
            }
        } else {
            // done, enable buttons
        }
    }
}