欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-05-28 20:14:03
...

渐变色圆弧形进度条,本文用 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)];

iOS 实现一个颜色渐变的弧形进度条 CAShapeLayer CAGradientLayer UIBezierPath这个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;
}

看结果

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

这里如果对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:图片和图层混合的图层。

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

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

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

第一行:

_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