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