Animate CALayer border change

人盡茶涼 提交于 2021-01-16 08:11:35

问题


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.


回答1:


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.




回答2:


Here's a swift solution for @David answer :

let colorAnimation = CABasicAnimation(keyPath: "borderColor")
colorAnimation.fromValue = UIColor.red.cgColor
colorAnimation.toValue = UIColor.blue.cgColor
view.layer.borderColor = UIColor.blue.cgColor

let widthAnimation = CABasicAnimation(keyPath: "borderWidth")
widthAnimation.fromValue = 2
widthAnimation.toValue = 4
widthAnimation.duration = 4
view.layer.borderWidth = 4

let bothAnimations = CAAnimationGroup()
bothAnimations.duration = 0.5
bothAnimations.animations = [colorAnimation, widthAnimation]
bothAnimations.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)

view.layer.add(bothAnimations, forKey: "color and width")



回答3:


If you just want to fade in the border you can also do this:

UIView.transition(with: self, duration: 0.3, options: .transitionCrossDissolve, animations: {

        self.layer.borderColor = UIColor.green.cgColor
        self.layer.borderWidth = 3

}, completion: nil)



回答4:


You can create a keyframe animation add it to your view.

//Create animation
        CAKeyframeAnimation *colorsAnimation = [CAKeyframeAnimation animationWithKeyPath:@"borderColor"];
        colorsAnimation.values = [NSArray arrayWithObjects: (id)[UIColor greenColor].CGColor,
                                  (id)[UIColor yellowColor].CGColor, nil];
        colorsAnimation.keyTimes = [NSArray arrayWithObjects:[NSNumber numberWithFloat:0.25],[NSNumber numberWithFloat:1.0], nil];
        colorsAnimation.calculationMode = kCAAnimationLinear;
        colorsAnimation.removedOnCompletion = NO;
        colorsAnimation.fillMode = kCAFillModeForwards;
        colorsAnimation.duration = 3.0f;

    //Create animation
    CAKeyframeAnimation *sizeAnimation = [CAKeyframeAnimation animationWithKeyPath:@"borderWidth"];
    sizeAnimation.values = [NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0],
                             [NSNumber numberWithFloat:5.0], nil];
    sizeAnimation.keyTimes = [NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0],[NSNumber numberWithFloat:3.0], nil];
    sizeAnimation.calculationMode = kCAAnimationLinear;
    sizeAnimation.removedOnCompletion = NO;
    sizeAnimation.fillMode = kCAFillModeForwards;
    sizeAnimation.duration = 3.0f;

    //Add animation
    [yoursubview.layer   addAnimation:colorsAnimation forKey:nil];
    [yoursubview.layer   addAnimation:sizeAnimation forKey:nil];


来源:https://stackoverflow.com/questions/21927994/animate-calayer-border-change

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!