rocket101 rocket101 - 5 months ago 74
Swift Question

Wait until animation finishes before moving on Swift

In the following code, how do I wait until the animation is done before moving on? I want the code to pulse "Sending" twice and "Sent" once, but it goes straight to "Sent", as far as I can tell"

UIView.animateWithDuration(1.0, delay: 0.25, options: UIViewAnimationOptions.CurveEaseIn, animations: {
self.countdownLabel.alpha = 0.0
}, completion: nil)
countdownLabel.text = "Sending"
UIView.animateWithDuration(1.0, delay: 0.25, options: UIViewAnimationOptions.CurveEaseIn, animations: {
self.countdownLabel.alpha = 1.0
}, completion: nil)
UIView.animateWithDuration(1.0, delay: 0.25, options: UIViewAnimationOptions.CurveEaseIn, animations: {
self.countdownLabel.alpha = 0.0
}, completion: nil)
countdownLabel.text = "Sending"
UIView.animateWithDuration(1.0, delay: 0.25, options: UIViewAnimationOptions.CurveEaseIn, animations: {
self.countdownLabel.alpha = 1.0
}, completion: nil)
UIView.animateWithDuration(1.0, delay: 0.25, options: UIViewAnimationOptions.CurveEaseIn, animations: {
self.countdownLabel.alpha = 0.0
}, completion: nil)
countdownLabel.text = "Sent"
cancelButton.setTitleColor(UIColor.blueColor(), forState: UIControlState.Normal)
UIView.animateWithDuration(1.0, delay: 0.25, options: UIViewAnimationOptions.CurveEaseIn, animations: {
self.countdownLabel.alpha = 1.0
}, completion: nil)


How can I wait for one part of the animation to finish before it moves on to the next part? Thanks!

Answer

That is what the completion handlers are for. Place the next animation inside the completion of the previous one.

Drop this in a playground. If you split it up in functions you can keep it readable. But this will be broken next Wednesday.

var view = UIView(frame: CGRect(x: 0, y: 0, width: 10, height: 10))
view.backgroundColor = UIColor.blackColor()


func animationOne() {
    UIView.animateWithDuration(1.0,
        delay: 0.0,
        options: nil,
        animations: {view.alpha = 1},
        completion: {finished in animationTwo()})
}

func animationTwo() {
    UIView.animateWithDuration(1.0,
        delay: 0.0,
        options: nil,
        animations: {view.alpha = 0},
        completion: {finished in animationThree()})
}

func animationThree() {
    UIView.animateWithDuration(1.0,
        delay: 0.0,
        options: nil,
        animations: {view.alpha = 1},
        completion: {finished in print("done")})

}

animationOne()

It appears swift2 doesn't like it when the options are nil:

options are now option sets which are arrays. nil has become []

UIView.animateWithDuration(2.0, delay: 0.0, options: [], animations: { () -> Void in

    self.view.alpha = 1.0

    }, completion: { (finished: Bool) -> Void in
     // next animation
})