UIView animation skips first animation

2019-08-29 22:54发布

问题:

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

回答1:

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);


回答2:

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!



标签: ios swift uiview