Warm tip: This article is reproduced from serverfault.com, please click

Animate CALayer border change

发布于 2014-02-21 07:27:42

I'm setting a border width and color to a UIView subclass this way:

- (void) setViewBorder
{
    self.layer.borderColor = [UIColor greenColor].CGColor;
    self.layer.borderWidth = 3.0f;
}

My question is: How can I animate this? Thanks.

Questioner
iOS Dev
Viewed
0
David Rönnqvist 2016-01-04 01:48:01

Both borderColor and borderWidth are animatable properties but since you are doing this in a view subclass outside of an UIView animation block, implicit animations (those that happen automatically when you change a value) are disabled.

If you want to animate these properties then you can do an explicit animation with a CABasicAnimation. Since you are animating two properties on the same layer, you can add them both to an animation group and only configure the duration, timing, etc. once. Note that the explicit animations are purely visual, the model value (the actual property) doesn't change when you add them. That is why you both configure the animation and set the model value.

CABasicAnimation *color = [CABasicAnimation animationWithKeyPath:@"borderColor"];
// animate from red to blue border ...
color.fromValue = (id)[UIColor redColor].CGColor;
color.toValue   = (id)[UIColor blueColor].CGColor;
// ... and change the model value
self.layer.borderColor = [UIColor blueColor].CGColor;

CABasicAnimation *width = [CABasicAnimation animationWithKeyPath:@"borderWidth"];
// animate from 2pt to 4pt wide border ...
width.fromValue = @2;
width.toValue   = @4;
// ... and change the model value
self.layer.borderWidth = 4;

CAAnimationGroup *both = [CAAnimationGroup animation];
// animate both as a group with the duration of 0.5 seconds
both.duration   = 0.5;
both.animations = @[color, width];
// optionally add other configuration (that applies to both animations)
both.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];

[self.layer addAnimation:both forKey:@"color and width"];

If you look at the documentation for CABasicAnimation under the section "Setting Interpolation values", you will see that it's not necessary to specify both the toValue and the fromValue like I did, so the code could be made slightly shorter. However, for clarity and readability (especially when you are starting with Core Animation) being more explicit can help you (and your coworker) understand the code.