依次执行功能
Performance of functions in turn
我有两个功能。
第一个是带有动画的功能,第二个是我在屏幕上显示文本的地方。
我通过按钮和摇动设备启动功能,但它们同时工作。
我需要先执行动画,然后在屏幕上显示文本。
例如,您可以每隔几秒执行一次。
目前有这段代码:
@IBAction func startButtnAtion(_ sender: UIButton) {
animateImage()
}
override func motionEnded(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
if motion == .motionShake {
animateImage()
}
}
func animateImage() {
let rotationAnimation = CABasicAnimation(keyPath: "transform.rotation")
rotationAnimation.fromValue = 0.0
rotationAnimation.toValue = Double.pi * 4
rotationAnimation.duration = 2.0
backGroundImage.layer.add(rotationAnimation, forKey: nil)
answerForQuest()
}
func answerForQuest() {
//some code
}
将第一个动画的委托 (CAAnimationDelegate) 设置到您的视图控制器。监听要触发的 animationDidStop 事件,一旦它被触发到 运行 你的第二个动画(显示文本)。这将允许第一个动画在开始下一个动画之前完成执行。
可以找到有关 CAAnimationDelegate 的文档 here。
我建议您使用 CATransaction.setCompletionBlock(_ block: (() -> Void)?)
这样动画方法将如下所示:
func animateImage() {
CATransaction.begin() // 1
let rotationAnimation = CABasicAnimation(keyPath:
"transform.rotation")
rotationAnimation.fromValue = 0.0
rotationAnimation.toValue = Double.pi * 4
rotationAnimation.duration = 2.0
CATransaction.setCompletionBlock { //2
self.answerForQuest()
}
backGroundImage.layer.add(rotationAnimation, forKey: nil)
CATransaction.commit() //3
}
通常,您可以从 CABasicAnimation
切换到使用 UIView
class func animate(withDuration duration: TimeInterval, animations: @escaping () -> Void, completion: ((Bool) -> Void)? = nil)
class,这样您的动画看起来将类似于此:
UIView.animate(withDuration:2.0, animations: {
self.backGroundImage.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi))
}, completion: { completed in
self.answerForQuest()
})
但在您的情况下不会,因为它正在计算开始状态和结束状态之间的差异,并为唯一发生变化的部分设置动画。
您可以创建一个变量来判断是否有正在进行的动画,并且在上一个动画结束之前不允许开始新的动画:
@IBAction func startButtnAtion(_ sender: UIButton) {
animateImage()
}
var isAnimating: Bool = false //1
func animateImage(){
guard !isAnimating else { //2
return
}
isAnimating = true //3
CATransaction.begin()
let rotationAnimation = CABasicAnimation(keyPath:
"transform.rotation")
rotationAnimation.fromValue = 0.0
rotationAnimation.toValue = Double.pi * 4
rotationAnimation.duration = 2.0
CATransaction.setCompletionBlock {
self.answerForQuest()
}
backGroundImage.layer.add(rotationAnimation, forKey: nil)
CATransaction.commit()
}
func answerForQuest()
{
isAnimating = false //4
print("answerForQuest")
}
我有两个功能。 第一个是带有动画的功能,第二个是我在屏幕上显示文本的地方。 我通过按钮和摇动设备启动功能,但它们同时工作。
我需要先执行动画,然后在屏幕上显示文本。 例如,您可以每隔几秒执行一次。
目前有这段代码:
@IBAction func startButtnAtion(_ sender: UIButton) {
animateImage()
}
override func motionEnded(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
if motion == .motionShake {
animateImage()
}
}
func animateImage() {
let rotationAnimation = CABasicAnimation(keyPath: "transform.rotation")
rotationAnimation.fromValue = 0.0
rotationAnimation.toValue = Double.pi * 4
rotationAnimation.duration = 2.0
backGroundImage.layer.add(rotationAnimation, forKey: nil)
answerForQuest()
}
func answerForQuest() {
//some code
}
将第一个动画的委托 (CAAnimationDelegate) 设置到您的视图控制器。监听要触发的 animationDidStop 事件,一旦它被触发到 运行 你的第二个动画(显示文本)。这将允许第一个动画在开始下一个动画之前完成执行。
可以找到有关 CAAnimationDelegate 的文档 here。
我建议您使用 CATransaction.setCompletionBlock(_ block: (() -> Void)?)
这样动画方法将如下所示:
func animateImage() {
CATransaction.begin() // 1
let rotationAnimation = CABasicAnimation(keyPath:
"transform.rotation")
rotationAnimation.fromValue = 0.0
rotationAnimation.toValue = Double.pi * 4
rotationAnimation.duration = 2.0
CATransaction.setCompletionBlock { //2
self.answerForQuest()
}
backGroundImage.layer.add(rotationAnimation, forKey: nil)
CATransaction.commit() //3
}
通常,您可以从 CABasicAnimation
切换到使用 UIView
class func animate(withDuration duration: TimeInterval, animations: @escaping () -> Void, completion: ((Bool) -> Void)? = nil)
class,这样您的动画看起来将类似于此:
UIView.animate(withDuration:2.0, animations: {
self.backGroundImage.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi))
}, completion: { completed in
self.answerForQuest()
})
但在您的情况下不会,因为它正在计算开始状态和结束状态之间的差异,并为唯一发生变化的部分设置动画。
您可以创建一个变量来判断是否有正在进行的动画,并且在上一个动画结束之前不允许开始新的动画:
@IBAction func startButtnAtion(_ sender: UIButton) {
animateImage()
}
var isAnimating: Bool = false //1
func animateImage(){
guard !isAnimating else { //2
return
}
isAnimating = true //3
CATransaction.begin()
let rotationAnimation = CABasicAnimation(keyPath:
"transform.rotation")
rotationAnimation.fromValue = 0.0
rotationAnimation.toValue = Double.pi * 4
rotationAnimation.duration = 2.0
CATransaction.setCompletionBlock {
self.answerForQuest()
}
backGroundImage.layer.add(rotationAnimation, forKey: nil)
CATransaction.commit()
}
func answerForQuest()
{
isAnimating = false //4
print("answerForQuest")
}