iOS 实现一个颜色渐变的弧形进度条 CAShapeLayer CAGradientLayer UIBezierPath

渐变色圆弧形进度条,本文用 CAShapeLayer CAGradientLayer UIBezierPath来实现。不过过程中需要注意mask这个概念,这个后面会详细说到。

1:首先创建CAGradientLayer,一个你需要的渐变的颜色的layer,并且加到父view上。

/**
 创建彩色layer 并把layer添加到view的layer上
 */
- (void)setMuchColor
{
    CAGradientLayer *layer = [CAGradientLayer layer];

    layer.frame = CGRectMake(0, 0, SELF_WIDTH, SELF_HEIGHT);

    layer.colors = @[(id)[HXLoopProgressView startColor].CGColor,
                     (id)[HXLoopProgressView endColor].CGColor];

    layer.startPoint = CGPointMake(0, 0);
    layer.endPoint = CGPointMake(1, 0); // 这个决定了你的颜色是横着放还是竖着放。
    layer.locations = @[@0.1, @0.6];

    self.muchColorLayer = layer;
    [self.layer addSublayer:layer];
}

这个location是颜色的位置

比方说有三种颜色是红色 绿色 蓝色。分割线是

(__bridge id)[UIColor redColor].CGColor,
(__bridge id)[UIColor greenColor].CGColor,
(__bridge id)[UIColor blueColor].CGColor];

/ 颜色分割线
    colorLayer.locations  = @[@(0.25), @(0.5), @(0.75)];

这个locations并不是表示颜色值所在位置,它表示的是颜色在Layer坐标系相对位置处要开始进行渐变颜色了.

2:紧接着,为这个彩色的layer加一个蒙层mask。

/**
 为彩色layer添加蒙层mask。这个mask有点讲究,有不清楚的可以看一下我页面的详细解说
 */
- (void)setMuchColoMask
{
    CAShapeLayer *mashLayer = [self generateMaskLayer];
    self.muchColorMashLayer = mashLayer;
    self.muchColorLayer.mask = mashLayer;
}

这个蒙层的layer的创建是下面这个

/**
 创建圆环,适合做蒙层,也适合画纯色图形

 @return CAShapeLayer
 */
- (CAShapeLayer *)generateMaskLayer
{
    CAShapeLayer *layer = [CAShapeLayer layer];
    layer.frame = self.bounds;

    UIBezierPath *paths = nil;
    paths = [UIBezierPath bezierPathWithArcCenter:CGPointMake(SELF_WIDTH / 2, SELF_HEIGHT / 2) radius:SELF_WIDTH / 2.5 startAngle:[HXLoopProgressView startAngle] endAngle:[HXLoopProgressView endAngle] clockwise:YES];

    layer.lineWidth = [HXLoopProgressView lineWidth];

    layer.fillColor = [UIColor clearColor].CGColor; // 这里一定要是透明色。跟mask有关,下面会详细说

    layer.strokeColor = [UIColor blackColor].CGColor;

    layer.lineCap = kCALineCapRound;

    layer.path = paths.CGPath;

    return layer;
}

3:为view的layer再加一层蒙层

/**
 为view的layer添加蒙层mask。
 */
- (void)settUI
{
    CAShapeLayer *layer = [self generateMaskLayer];
    [self.layer addSublayer:layer];
    self.layer.mask = layer;
}

看结果

这里如果对mask不太熟悉的人就可能会有很多疑惑。下面给大家梳理一下mask的特性。

mask是蒙层,对mask而言有两个影响因素,一个是backgroundcolor的alpha 一个contents里面图片的alpha。

mask中backgroudcolor的alpha比contents的图片alpha要强。

 ☆ 能看见底部 0 : 不能看见底部   0-1 :混合

1:backgroudcolor中alpha 为1 ,则 不论contents中图片alpha是否透明,均可看见图层。

2:backgroudcolor中alpha 为0

a:contents图片alpha 为 0 :不能看见图层。

b:contents图片alpha 为 1 :能看见图片中为1的图片轮廓下的图层。

c:contents图片alpha 为 0-1:能看到图片轮廓下图片和图层混合的图层。

3:backgroudcolor中alpha 为 0-1:

a:contents图片alpha 为 0 :能看到蒙层的图层:全部

b:contents图片alpha 为 1 :则看到图片轮廓是是实得,其余是虚的图像。

c:contents图片alpha 为 0-1:图片和图层混合的图层。

如果还不明白 则下面讲一个例子

左边是正常的图,右边是加了蒙层的图。

第一行:

_firstLayer.backgroundColor = [UIColor colorWithRed:1 green:1 blue:1 alpha:0.5].CGColor;

    _firstLayer.contents = (id)[UIImage imageNamed:@"bgTransparent"].CGImage; 这个图片半透明

所以是蒙层和底下图混合显示

第二行:

    _topLayer.backgroundColor = [UIColor colorWithRed:1 green:1 blue:1 alpha:1].CGColor;

    _topLayer.contents = (id)[UIImage imageNamed:@"bgTransparent"].CGImage; 图片半透明

只要backgroudecolor的alpha为1 ,蒙层什么透明度都不好使了。

第三行:

    _middleLayer.backgroundColor = [UIColor colorWithRed:1 green:1 blue:1 alpha:0.5].CGColor;

    _middleLayer.contents = (id)[UIImage imageNamed:@"bgNonTransparent"].CGImage; 图片不透明了。

则图片轮廓处显示为实的,其余是backgroudcolor的半透明。

第四行 : 牵扯子layer。

- (void)configureUndefinedMaskLayer{
    
    //add gradient layer to imageview layer
    _gradientLayer = [CAGradientLayer layer];
    _gradientLayer.frame =  _bottomImageview.bounds;
    [self setupGradientlayer:_gradientLayer];
    [_bottomImageview.layer addSublayer:_gradientLayer];
    
    //init mask layer
    _btmLayer = [CALayer layer];
    _btmLayer.frame = CGRectMake(30, 30, _bottomImageview.bounds.size.width - 30 * 2, _bottomImageview.bounds.size.height - 30 * 2);
    _btmLayer.contents = (id)[UIImage imageNamed:@"bgTransparent"].CGImage;
    _btmLayer.contentsGravity = kCAGravityResizeAspect;
    _btmLayer.backgroundColor = [UIColor colorWithRed:1 green:1 blue:1 alpha:0.5].CGColor;
    
    _gradientLayer.mask = _btmLayer;
}

好,总结以上

看上面彩色的进度圆环,加在彩色layer上的蒙层是为了只显示出彩色的layer的轮廓,同样layer加载到view上,因为没有加到view的layer上,所以view的背景颜色和彩色的layer的圆弧 一同显示。

接着加一个maks 加到view的layer上,这个时候就显示的是有彩色的也有没有进度的灰色。这个灰色是背景色。

想看源码 可以下载https://github.com/Khaidetiankong1661/HXLoopProgress

猜你喜欢

转载自blog.csdn.net/qq_27909209/article/details/81538170