CAShapeLayer是一个通过矢量图形而不是bitmap来绘制的图层CALayer的子类。你指定诸如颜色和线宽等属性,用CGPath来定义想要绘制的图形,最后CAShapeLayer就自动渲染出来了。
当然,你也可以用Core Graphics直接向原始的CALyer的内容中绘制一个路径,相比直下,使用CAShapeLayer有以下一些优点:
渲染快速。CAShapeLayer使用了硬件加速,绘制同一图形会比用Core Graphics快很多。
高效使用内存。一个CAShapeLayer不需要像普通CALayer一样创建一个寄宿图形,所以无论有多大,都不会占用太多的内存。
不会被图层边界剪裁掉。一个CAShapeLayer可以在边界之外绘制。你的图层路径不会像在使用Core Graphics的普通CALayer一样被剪裁掉。
不会出现像素化。当你给CAShapeLayer做3D变换时,它不像一个有寄宿图的普通图层一样变得像素化。
而在项目中,很多时候就需要用到一些图层的小动画,更加来吸引人的眼光,让整个项目给人一种焕然一新而又不乏味的感觉,这样给用户的体验就会上一个层次。
以下就简单介绍一些CAShapeLayer的实现小动画效果:
//绘制圆环
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:origin radius:radius startAngle:-M_PI + M_PI_2 endAngle:M_PI + M_PI_2 clockwise:YES];
_backGroundShapeLayer.path = path.CGPath;
_showProgressShapeLayer.path = path.CGPath;
//给圆环添加渐变层
CALayer *gradientLayer = [CALayer layer];
CAGradientLayer *leftGradient = [CAGradientLayer layer];
leftGradient.frame = CGRectMake(-showLineWidth/2, -showLineWidth/2, self.bounds.size.width / 2 + showLineWidth/2, self.bounds.size.height + showLineWidth);
// leftGradient.colors = @[(id)[UIColor yellowColor].CGColor,
// (id)[UIColor greenColor].CGColor];
leftGradient.colors = @[(id)HEXCOLOR(0x00baff).CGColor,
(id)labelSkyBuleColor.CGColor];
[leftGradient setLocations:@[@0.3, @0.6, @1]];
CAGradientLayer *rightGradient = [CAGradientLayer layer];
rightGradient.frame = CGRectMake(self.bounds.size.width / 2, -showLineWidth/2, self.bounds.size.width / 2 + showLineWidth / 2, self.bounds.size.height + showLineWidth);
// rightGradient.colors = @[(id)[UIColor yellowColor].CGColor,
// (id)[UIColor greenColor].CGColor];
rightGradient.colors = @[(id)HEXCOLOR(0x00baff).CGColor,
(id)labelSkyBuleColor.CGColor];
[rightGradient setLocations:@[@0.3, @0.6, @1]];
[gradientLayer addSublayer:leftGradient];
[gradientLayer addSublayer:rightGradient];
[gradientLayer setMask:self.showProgressShapeLayer];
[self.layer addSublayer:gradientLayer];
//初始化背景圆环和绘制颜色圆环的路径图层
- (CAShapeLayer *)backGroundShapeLayer
{
if (!_backGroundShapeLayer)
{
_backGroundShapeLayer = [CAShapeLayer layer];
_backGroundShapeLayer.lineCap = kCALineCapRound;
_backGroundShapeLayer.lineWidth = showLineWidth;
_backGroundShapeLayer.fillColor = [UIColor clearColor].CGColor;
}
return _backGroundShapeLayer;
}
- (CAShapeLayer *)showProgressShapeLayer
{
if (!_showProgressShapeLayer)
{
_showProgressShapeLayer = [CAShapeLayer layer];
_showProgressShapeLayer.lineCap = kCALineCapRound;
_showProgressShapeLayer.lineWidth = showLineWidth;
_showProgressShapeLayer.fillColor = [UIColor clearColor].CGColor;
_showProgressShapeLayer.strokeColor = [UIColor whiteColor].CGColor;
}
return _showProgressShapeLayer;
}
当上面的工作准备好了,既可以通过核心动画,配合圆环的绘制进行相关的动画效果,如下:
/**
显示动画
@param shapeLayer 动画图层
@param duration 动画时间
*/
- (void)showAnimationWithShapeLayer:(CAShapeLayer *)shapeLayer andAnimationDuration:(CGFloat)duration andToValue:(CGFloat)endValue
{
//添加动画
CABasicAnimation *pathAnima = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
pathAnima.duration = duration;
pathAnima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
pathAnima.fromValue = @(0.0);
pathAnima.toValue = @(endValue);
pathAnima.fillMode = kCAFillModeForwards;
pathAnima.removedOnCompletion = NO;
[shapeLayer addAnimation:pathAnima forKey:@"strokeEndAnimation"];
}
然后数据的配合使用,可通过具体的参数进行相关的路径百分比来绘制圆环的进度
[self showAnimationWithShapeLayer:self.showProgressShapeLayer andAnimationDuration:2.0f andToValue:progress];
而实现一个直线进度条可以这样实现:
//创建
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
//线条的开始和结束进度
shapeLayer.strokeEnd = 1.0f;
shapeLayer.strokeStart = 0.0f;
//设置圆角
shapeLayer.lineJoin = kCALineJoinRound;
shapeLayer.lineCap = kCALineCapRound;
//描述路径
UIBezierPath *path = [UIBezierPath bezierPath];
//设置起点
[path moveToPoint:CGPointMake(leftAndRightSpace, LineCenterY)];
//绘制第一条线
[path addLineToPoint:CGPointMake(self.bounds.size.width - leftAndRightSpace, LineCenterY)];
//绘制路径
shapeLayer.path = path.CGPath;
//绘制填充颜色
shapeLayer.fillColor = [UIColor clearColor].CGColor;
//绘制线条大小
shapeLayer.lineWidth = LineWidth;
//绘制线条颜色
shapeLayer.strokeColor = color.CGColor;
//加入图层
[self.layer addSublayer:shapeLayer];
/**
显示动画
@param shapeLayer 动画图层
@param duration 动画时间
*/
- (void)showAnimationWithShapeLayer:(CAShapeLayer *)shapeLayer andAnimationDuration:(CGFloat)duration
{
//添加动画
CABasicAnimation *pathAnima = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
pathAnima.duration = duration;
pathAnima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
pathAnima.fromValue = @(0.0);
pathAnima.toValue = @(1.0);
pathAnima.fillMode = kCAFillModeForwards;
pathAnima.removedOnCompletion = NO;
[shapeLayer addAnimation:pathAnima forKey:@"strokeEndAnimation"];
}
其实际调用的方法和圆环也是一样,只需要把外部的参数传递过来,根据相关的参数进行进度的绘制。
大千世界,求同存异;相遇是缘,相识是份,相知便是“猿粪”(缘分)
From MZou