Swift - 具有持续时间的 CoreAnimation
Swift - CoreAnimation with duration
试图了解 CoreAnimation 和完成处理程序。
为什么这段代码是一次性发生的,而不是在 5.0 秒的时间内发生?
我试图让它达到 运行 6 次,每次持续 5 秒,总共 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, delay: 0.0, options: [], animations: {
self.myBox.layer.borderColor = self.getRandom()
}, completion: { finished in
print("complete")
UIView.animate(withDuration: 5.0, delay: 0.0, options: [], 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),
options: [],
animations: {
self.myBox.layer.borderColor = self.getRandom()
}, 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 开始。)
试图了解 CoreAnimation 和完成处理程序。
为什么这段代码是一次性发生的,而不是在 5.0 秒的时间内发生?
我试图让它达到 运行 6 次,每次持续 5 秒,总共 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, delay: 0.0, options: [], animations: {
self.myBox.layer.borderColor = self.getRandom()
}, completion: { finished in
print("complete")
UIView.animate(withDuration: 5.0, delay: 0.0, options: [], 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),
options: [],
animations: {
self.myBox.layer.borderColor = self.getRandom()
}, 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 开始。)