CAShapeLayer的简单应用

CAShapeLayer是一个通过矢量图形而不是bitmap来绘制的图层CALayer的子类。你指定诸如颜色和线宽等属性,用CGPath来定义想要绘制的图形,最后CAShapeLayer就自动渲染出来了。
当然,你也可以用Core Graphics直接向原始的CALyer的内容中绘制一个路径,相比直下,使用CAShapeLayer有以下一些优点:

渲染快速。CAShapeLayer使用了硬件加速,绘制同一图形会比用Core Graphics快很多。
高效使用内存。一个CAShapeLayer不需要像普通CALayer一样创建一个寄宿图形,所以无论有多大,都不会占用太多的内存。
不会被图层边界剪裁掉。一个CAShapeLayer可以在边界之外绘制。你的图层路径不会像在使用Core Graphics的普通CALayer一样被剪裁掉。
不会出现像素化。当你给CAShapeLayer做3D变换时,它不像一个有寄宿图的普通图层一样变得像素化。

而在项目中,很多时候就需要用到一些图层的小动画,更加来吸引人的眼光,让整个项目给人一种焕然一新而又不乏味的感觉,这样给用户的体验就会上一个层次。
以下就简单介绍一些CAShapeLayer的实现小动画效果:


CAShapeLayer的简单应用_第1张图片
圆环进度条
//绘制圆环
 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的简单应用_第2张图片
直线进度条.gif
    //创建
    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

你可能感兴趣的:(CAShapeLayer的简单应用)