CAShapeLayer Path Animation

 原创    2019-09-27

CAShapeLayer动画时一个小技巧,避免直接赋值path,而使用strokeEnd可以自定义动画效果。

在实际项目开发中,遇到了使用CAShapeLayer绘制圆弧的场景,根据业务进度从0~360度步进式填充圆弧。最开始使用直接修改path的方式:

shapeLayer.path = newPath.CGPath;

根据CAlayer的动画原理可知,此时shapeLayer会有一个隐式动画。CAlayer的隐式动画的一个问题就是动画是线性的,往往达不到我们想要的效果。这个时候就需要我们创建自定义动画。

对于CAShapeLayer来说,想要实现path步进效果的自定义动画,需要借助其strokeStart,strokeEnd属性。

典型的实现方式如下:

//创建CAShapeLayer,填充完整的path,并设置strokeEnd = 0.0
UIBezierPath *bezierPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(100.0, 100.0)
		                                                     radius:100.0
		                                                 startAngle:-M_PI_2*3
		                                                   endAngle:M_PI_2
		                                                  clockwise:YES];
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.strokeColor = [UIColor redColor].CGColor;
shapeLayer.fillColor = [UIColor clearColor].CGColor;
shapeLayer.lineWidth = 2;
shapeLayer.path = bezierPath.CGPath;
shapeLayer.lineCap = kCALineCapRound;
shapeLayer.strokeStart = 0.0;
shapeLayer.strokeEnd = 0.0;//取值范围0-1
...

[shapeLayer removeAllAnimations];
shapeLayer.strokeEnd = startValue;
  
//添加自定义动画,作用于strokeEnd,并设置动画完成时维持终态
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
animation.duration = 0.7;
animation.fromValue = [NSNumber numberWithFloat:startValue];
animation.toValue = [NSNumber numberWithFloat:endValue];
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
[shapeLayer addAnimation:animation forKey:nil];

相关文章:

iOS Asset Catalog and Bundle
iOS安全:Tweak开发环境及入门
iOS TestFlight的局限性及改进措施
iOS 真机和模拟器HTTPS Charles抓包指南
统计iOS 8.0及之后所有正式版版本号

发表留言

您的电子邮箱地址不会被公开,必填项已用*标注。发布的留言可能不会立即公开展示,请耐心等待审核通过。