Выполнение функций по очереди - PullRequest
0 голосов
/ 28 октября 2019

У меня есть две функции. Первая - это функция с анимацией, а вторая - когда я показываю текст на экране. Я запускаю функции с кнопки и при встряхивании устройства, но они работают одновременно.

Мне нужно сначала выполнить анимацию, а затем текст был отображен на экране. И вы можете сделать это, например, раз в несколько секунд.

Пока есть этот код:

@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
}

Ответы [ 2 ]

1 голос
/ 28 октября 2019

Я предлагаю вам использовать 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 на использование class func animate(withDuration duration: TimeInterval, animations: @escaping () -> Void, completion: ((Bool) -> Void)? = nil) с UIView класса. поэтому ваша анимация будет выглядеть примерно так:

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")
}
0 голосов
/ 28 октября 2019

Установите делегат (CAAnimationDelegate) для первой анимации на вашем контроллере представления. Прослушайте событие animationDidStop, которое должно быть запущено, и как только оно будет запущено, чтобы запустить вторую анимацию (показа текста). Это позволит завершить выполнение первой анимации перед началом следующей анимации.

Документация по CAAnimationDelegate находится здесь здесь .

...