简体   繁体   中英

Can't animate UILabels with Swift

I'm trying to animate labels on view. I want to show label 1, then label 2, then remove label2. But label2 is always removed. If I delete the last keyframe block (which "removes" label2), it shows properly).

Here's the code:

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)

    let pos1 = self.label1.frame
    let pos2 = self.label2.frame

    self.label1.frame = CGRect(x: self.view.center.x, y: -10, width: 0, height: 0)
    self.label2.frame = CGRect(x: pos2.origin.x, y: self.view.frame.height+10, width: 0, height: 0)

    UIView.animateKeyframesWithDuration(1.5, delay: 0.0, options: nil, animations: {
        UIView.addKeyframeWithRelativeStartTime(0.0, relativeDuration: 0.4, animations: {
            self.label1.frame = pos1
        })

        UIView.addKeyframeWithRelativeStartTime(0.4, relativeDuration: 0.4, animations: {
            self.label2.frame = pos2
        })

        UIView.addKeyframeWithRelativeStartTime(1.0, relativeDuration: 0.5, animations: {
            self.label1.frame = CGRect(x: pos2.origin.x, y: self.view.frame.height + 10, width: 0, height: 0)
        })

    }, completion: nil)
}

From the reference , the timing parameters in addKeyframeWithRelativeStartTime... are values in the range of 0..1 which are interpreted relative to the entire duration of the animation and NOT a value in seconds. So specifying a keyframe with a start time of 1.0 says to start the animation at the END of the entire animation. Change the start times to 0.0 / 1.5, 0.5 / 1.5, 1.0 / 1.5 and the durations to 0.4 / 1.5 and 0.5 / 1.5.

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    let pos1 = self.label1.frame
    let pos2 = self.label2.frame

    self.label1.frame = CGRect(x: self.view.center.x, y: -10, width: 0, height: 0)
    self.label2.frame = CGRect(x: pos2.origin.x, y: self.view.frame.height + 10, width: 0, height: 0)

    UIView.animateKeyframes(withDuration: 1.5, delay: 0.0, options: [], animations: {
        UIView.addKeyframe(withRelativeStartTime: 0.0 / 1.5, relativeDuration: 0.4 / 1.5, animations: {
            self.label1.frame = pos1
        })

        UIView.addKeyframe(withRelativeStartTime: 0.4 / 1.5, relativeDuration: 0.4 / 1.5, animations: {
            self.label2.frame = pos2
        })

        UIView.addKeyframe(withRelativeStartTime: 1.0 / 1.5, relativeDuration: 0.5 / 1.5, animations: {
            self.label1.frame = CGRect(x: pos2.origin.x, y: self.view.frame.height + 10, width: pos1.size.width, height: pos1.size.height)
        })

    }, completion: nil)
}

It seems there are also issues animating the size of views. Only the final size is used (note that in this case you should see the labels start from 0x0 and grow to their final size, but they don't) So setting the size in the final frame to 0x0 makes label1 have that size through the whole animation. Change the code to maintain the size and it seems to work fine. If you really want to animate the size to zero you'll probably need to animate the transform property through scaling.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM