Swift-带有持续时间的CoreAnimation

问题描述

试图了解CoreAnimation和完成处理程序。
为什么这段代码一次发生,而不是在5.0秒内发生?
我试图让它以5秒的时间运行6次,每次持续30秒,并且每5秒打印一次“完整”。

    func animateBox() {

        UIView.animate(withDuration: 5.0,delay: 0.0,options: [],animations: {
            self.myBox.layer.borderColor = self.getRandom()
        },completion: {finished in
            print("complete")
        })
    
    }

    @objc func buttonTapped() {
        
        for _ in 1...6 {
            animateBox()
            print("animate")
        }
    }

解决方法

for _ in 1...6 {会立即执行,因此animateBox在瞬间被调用了6次,一次又一次。

您想要做的是在上一个动画完成时间(在动画完成时调用)的内部 中调用每个动画块。像这样:

UIView.animate(withDuration: 5.0,delay: 0.0,options: [],animations: {
    self.myBox.layer.borderColor = self.getRandom()
},completion: { finished in
    print("complete")

    UIView.animate(withDuration: 5.0,animations: {
        self.myBox.layer.borderColor = self.getRandom()
    },completion: { finished in
        print("complete")

        UIView.animate(withDuration: 5.0,animations: {
            self.myBox.layer.borderColor = self.getRandom()
        },completion: { finished in
            print("complete")

            ...
        })
    })
})

但这将导致巨大的完成金字塔……相反,请尝试使用animateKeyframes

let totalDuration = CGFloat(30)
let relativeIndividualDuration = CGFloat(1) / CGFloat(6)

UIView.animateKeyframes(withDuration: totalDuration,delay: 0,options: .calculationModeCubic,animations: {
    UIView.addKeyframe(withRelativeStartTime: 0.0,relativeDuration: relativeIndividualDuration) {
        self.myBox.layer.borderColor = self.getRandom()
    }

    UIView.addKeyframe(withRelativeStartTime: relativeIndividualDuration,relativeDuration: relativeIndividualDuration) {
        self.myBox.layer.borderColor = self.getRandom()
    }

    UIView.addKeyframe(withRelativeStartTime: relativeIndividualDuration * 2,relativeDuration: relativeIndividualDuration) {
        self.myBox.layer.borderColor = self.getRandom()
    }

    ...
})
,

您可以对动画进行排序的另一种方法是使用延迟参数,并在第一步之后为每一步添加一个延迟:

func animateBox(step: Int) {
    let duration = 5.0
    UIView.animate(withDuration: duration,delay: duration * Double(step),completion: {finished in
        print("complete")
    })

}

@objc func buttonTapped() {
    
    for index in 0...5 {
        animateBox(step: index)
        print("animating step \(index)")
    }
}

(请注意,我将您的循环更改为从 0...5 运行,因此 delay =step * duration 将从 0 开始。)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...