CABasicAnimation with keypath "bounds" not working

11,867

Your code does actually work. If you run your code and then switch on View Debugging in Xcode, you will see that the height of the label has increased. The "problem" is that a UILabel in iOS 8 draws itself (its text and its background, if it has one) the same way even after its layer height has been artificially increased in this way. (I believe that this is because the label draws itself with a special clipping region that is based on its text contents.)

To prove this to yourself, try it on a plain vanilla UIView (with a colored background) instead of a label. I've taken the liberty of cleaning up your code (you should never misuse fillMode and removedOnCompletion the way you are doing - it just shows a lack of understand of what animation is):

    let fromValue = view2.layer.bounds.height
    let toValue = view2.layer.bounds.height + 50
    CATransaction.setDisableActions(true)
    view2.layer.bounds.size.height = toValue
    let positionAnimation = CABasicAnimation(keyPath: "bounds.size.height")
    positionAnimation.fromValue = fromValue
    positionAnimation.toValue = toValue
    positionAnimation.duration = 1
    view2.layer.addAnimation(positionAnimation, forKey: "bounds")

You will see that that works perfectly. Now change view2 back to textLabel throughout. It still works, it's just that there is nothing to see.

Another way to prove this to yourself is to drop the whole animation and just change the label's layer height:

    self.textLabel.layer.bounds.size.height += 50

You will not see anything happen. So there is no bug in your animation; it's all about the way labels are drawn.

You can make the change visible by changing the view instead of the layer:

    self.textLabel.bounds.size.height += 50

One additional "problem", though, is that the animation is not animating. Again this is because labels are drawn in a special way.

So whatever it is you're trying to accomplish it, you'll have to do it in a different way. You might have a clear label in front of a colored view and animate the change in height of the view; we've already proven that that works.

Share:
11,867

Related videos on Youtube

KSC
Author by

KSC

Updated on June 04, 2022

Comments

  • KSC
    KSC almost 2 years

    I have the following code to animation bounds property of CALayer using CABasicAnimation. But the code doesn't seem to work.

        let fromValue = textLabel.layer.bounds
        let toValue = CGRectMake(textLabel.layer.bounds.origin.x, textLabel.layer.bounds.origin.y,   textLabel.layer.bounds.width, textLabel.layer.bounds.height + 50)
    
        let positionAnimation = CABasicAnimation(keyPath: "bounds")
        positionAnimation.fromValue = NSValue(CGRect: fromValue)
        positionAnimation.toValue = NSValue(CGRect: toValue)
        positionAnimation.duration = 1
        positionAnimation.fillMode = kCAFillModeBoth
        positionAnimation.removedOnCompletion = false
    
        textLabel.layer.addAnimation(positionAnimation, forKey: "bounds")
    
    • matt
      matt over 9 years
      What's your evidence that it doesn't work? Increasing the height of the label doesn't change the way the text is displayed, so what difference do you expect to see?
  • KSC
    KSC over 9 years
    Thanks for the answer, yea i realized that the animation doesnt show up for UILabels because there is special handling which done by themselves. Also I have used fillMode and removeOnCompletion because I want the actual layer to get updated and do something with the animation if it does complete.