PugLvr28
PugLvr28

Reputation: 111

UIView animation skips first animation

Very new to this sorry!

As soon as I run press the button "press" The background color of UIView "Background" changes instantly to blue and then animates to purple, completely skipping the animation to yellow, then to blue.

What have I done wrong?

  @IBAction func Press(sender: AnyObject) {

UIView.animateWithDuration(5, animations: {
self.Background.backgroundColor = UIColor.yellowColor()
self.Background.backgroundColor = UIColor.blueColor()
self.Background.backgroundColor = UIColor.purpleColor()
}, completion:{(Bool)  in
println("COLOR CHANGED")
})
}

Upvotes: 0

Views: 713

Answers (2)

rakeshbs
rakeshbs

Reputation: 24572

You cannot animate more than one state change to the same property in a single UIView.animateWithDuration call. It will just animate to the last state change(like in your case). Instead you can chain them together using the completionBlock.

UIView.animateWithDuration(5/3.0, animations: {

    self.view.backgroundColor = UIColor.yellowColor()

    }, completion:{ finished1 in
        UIView.animateWithDuration(5/3.0, animations: {

            self.view.backgroundColor = UIColor.blueColor()

            }, completion:{finished2  in
                UIView.animateWithDuration(5/3.0, animations: {

                    self.view.backgroundColor = UIColor.purpleColor()

                    }, completion:{finished3  in

                        println("COLOR CHANGED")
                })
        })
})

Or you can use keyframe animations, specifying intermediate frames like the following. The relativeDuration should be a value between 0 and 1, indicating the relative duration of one keyframe. for example if the whole animation is 3 seconds and relativeDuration is (1/3), then that keyframe will animate for 3/3 = 1 second.

relativeStartTime is similarly the relative time after which the keyframe starts with respect to the duration of the whole animation. for example if the whole animation is 3 seconds and relativeStartTime is (1/3), then that keyframe will start after 1 second

var duration = 5.0;
var relativeDuration = 1.0/3;

UIView.animateKeyframesWithDuration(duration, delay: 0, options: nil, animations: {
    UIView.addKeyframeWithRelativeStartTime(0, relativeDuration: relativeDuration, animations: {
        self.view.backgroundColor = UIColor.yellowColor()
    })
    UIView.addKeyframeWithRelativeStartTime(relativeDuration, relativeDuration: relativeDuration, animations: {
        self.view.backgroundColor = UIColor.blueColor()
    })
    UIView.addKeyframeWithRelativeStartTime(2 * relativeDuration, relativeDuration: relativeDuration, animations: {
        self.view.backgroundColor = UIColor.purpleColor()

    })
    }, completion:nil);

Upvotes: 3

matt
matt

Reputation: 534925

Right, because that is all one change to one property. You need to make this three successive different animations. First animate to yellow; when that ends, now make a whole new animation to blue; then make a whole new animation to purple.

The easiest way to chain them is to put each new animation in the completion handler of the previous animation. Like this (you will need to change some other things because I refuse to write code where functions and variables start with capitals):

@IBAction func press(sender: AnyObject) {
    UIView.animateWithDuration(5.0/3.0, animations: {
        self.background.backgroundColor = UIColor.yellowColor()
        }, completion:{(Bool)  in
            UIView.animateWithDuration(5.0/3.0, animations: {
                self.background.backgroundColor = UIColor.blueColor()
                }, completion:{(Bool)  in
                    UIView.animateWithDuration(5.0/3.0, animations: {
                        self.background.backgroundColor = UIColor.purpleColor()
                        }, completion:{(Bool)  in
                            println("COLOR CHANGED")
                    })
            })
    })
}

On iOS 8 there's also a more elegant (but harder) way, which is to use a keyframe animation. But to get started I would advise you to do it the easy way first!

Upvotes: 2

Related Questions