依次执行功能

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")
}