iOS开发CAGradientLayer,CAShapeLayer及UIBezierPath实现环形彩色进度条

释放双眼,带上耳机,听听看~!

结合CAGradientLayer,CAShapeLayer及UIBezierPath实现环形彩色进度条
这里写图片描述

CAGradientLayer: 渐变色
CAShapeLayer: 提供显示图层渲染需要结合UIBezierPath
UIBezierPath: 提供路径

CAShapeLayer:
1, CAShapeLayer继承自CALayer,可使用CALayer的所有属性
2, CAShapeLayer需要和贝塞尔曲线配合使用才有意义。
Shape:形状
贝塞尔曲线可以为其提供形状,而单独使用CAShapeLayer是没有任何意义的。
3, 使用CAShapeLayer与贝塞尔曲线可以实现不在view的DrawRect方法中画出一些想要的图形

关于CAShapeLayer和DrawRect的比较
DrawRect:DrawRect属于CoreGraphic框架,占用CPU,消耗性能大
CAShapeLayer:CAShapeLayer属于CoreAnimation框架,通过GPU来渲染图形,节省性能。动画渲染直接提交给手机GPU,不消耗内存

贝塞尔曲线与CAShapeLayer的关系
1,CAShapeLayer中shape代表形状的意思,所以需要形状才能生效
2,贝塞尔曲线可以创建基于矢量的路径
3,贝塞尔曲线给CAShapeLayer提供路径,CAShapeLayer在提供的路径中进行渲染。路径会闭环,所以绘制出了Shape
4,用于CAShapeLayer的贝塞尔曲线作为Path,其path是一个首尾相接的闭环的曲线,即使该贝塞尔曲线不是一个闭环的曲线

创建 渐变色的进度条之前先了解一下CAGradientLayer 和 CAShapeLayer的基本用法, 至于UIBezierPath则在前面的文章中有详细的说明

CAGradientLayer

CAGradientLayer是单位坐标系

1,CAGradientLayer的坐标系统是从(0,0)到(1,1)绘制的矩形
2,CAGradientLayer的frame值的size不为正方形的话,坐标系统会被拉伸
3,CAGradientLayer的startPoint和endPoint会直接决定颜色的绘制方向
4,CAGradientLayer的颜色分割点时以0到1的比例来计算的


@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//初始化imageView
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"2.jpg"]];
imageView.frame = CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height);
imageView.center = self.view.center;
[self.view addSubview:imageView];
//初始化渐变层
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
//设置渐变层的 rect
gradientLayer.frame = imageView.bounds;
[imageView.layer addSublayer:gradientLayer];
//设置渐变颜色方向, startPoint和endPoint会直接决定颜色的绘制方向
gradientLayer.startPoint = CGPointMake(0, 0);
gradientLayer.endPoint = CGPointMake(0, 1);
//设定颜色组
gradientLayer.colors = @[(id)[UIColor clearColor].CGColor,
(id)[UIColor colorWithRed:0.000 green:1.000 blue:0.502 alpha:1.000].CGColor,
(id)[UIColor purpleColor].CGColor,
(id)[UIColor blueColor].CGColor];
//设定颜色分割点
gradientLayer.locations = @[@(0.2f) , @(0.6f) , @(0.7f) , @(0.9f) ];
}

CAShapeLayer: 提供显示图层渲染需要结合UIBezierPath

//创建出CAShapeLayer
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
//设置shapeLayer的尺寸和位置
shapeLayer.frame = CGRectMake(0, 0, 200, 200);
//设置中心position
shapeLayer.position = self.view.center;
//填充颜色为ClearColor
shapeLayer.fillColor = [UIColor clearColor].CGColor;
//设置线条的宽度和颜色
shapeLayer.lineWidth = 1.0f;
shapeLayer.strokeColor = [UIColor redColor].CGColor;
//填充色
shapeLayer.fillColor = [UIColor clearColor].CGColor;
//线 颜色
shapeLayer.strokeColor = [UIColor redColor].CGColor;
//创建出圆形贝塞尔曲线
UIBezierPath *circlePath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 200, 200)];
//让贝塞尔曲线与CAShapeLayer产生联系
shapeLayer.path = circlePath.CGPath;
//添加并显示
[self.view.layer addSublayer:shapeLayer]
//设置stroke起始点
shapeLayer.strokeStart = 0.5;
shapeLayer.strokeEnd = 0.85;

好吧, 暂时就这么多吧
开始实现 进度条

#import "ZHZProgressView.h"
#define VRadians(x) (M_PI*(x)/180.0) //把角度转换成PI的方式
#define kLineW 8 //弧线的宽度
#define kViewW self.frame.size.width
#define kViewH self.frame.size.height
@interface ZHZProgressView () {
UILabel *label;
}
@property (nonatomic, strong)CAShapeLayer *shapeLayer;
@end
@implementation ZHZProgressView
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
CGFloat labelW = self.frame.size.width - kLineW * 2;
CGFloat labelH = self.frame.size.height - kLineW * 2;
label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, labelW, labelH)];
label.center = self.center;
label.backgroundColor = [UIColor clearColor];
label.textColor = [UIColor blueColor];
label.font = [UIFont systemFontOfSize:20];
label.textAlignment = NSTextAlignmentCenter;
[self addSubview:label];
}
return self;
}
- (void)drawRect:(CGRect)rect {
//设置路径
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.frame.size.width / 2.0, self.frame.size.height / 2.0) radius:self.frame.size.width / 2.0 - kLineW startAngle:VRadians(-210) endAngle:VRadians(30) clockwise:YES];
path.lineWidth = kLineW;
path.lineJoinStyle = kCGLineJoinRound;
path.lineCapStyle = kCGLineCapRound;
[[UIColor colorWithWhite:0.667 alpha:0.343] set];
[path stroke];
self.shapeLayer = [CAShapeLayer layer];
self.shapeLayer.frame = self.bounds;
self.shapeLayer.fillColor = [UIColor clearColor].CGColor;
self.shapeLayer.strokeColor = [UIColor redColor].CGColor;
self.shapeLayer.lineJoin = kCALineCapRound;
self.shapeLayer.lineCap = kCALineCapRound;
self.shapeLayer.lineWidth = kLineW;
self.shapeLayer.path = path.CGPath;
CALayer *gradientLayer = [CALayer layer];
CAGradientLayer *gradientLayer1 =  [CAGradientLayer layer];
gradientLayer1.frame = CGRectMake(0, 0, self.frame.size.width/2, self.frame.size.height);
gradientLayer1.colors = @[
(id)[UIColor redColor].CGColor,
(id)[UIColor greenColor].CGColor,
];
[gradientLayer1 setStartPoint:CGPointMake(0.5, 1)];
[gradientLayer1 setEndPoint:CGPointMake(0.5, 0)];
[gradientLayer addSublayer:gradientLayer1];
CAGradientLayer *gradientLayer2 =  [CAGradientLayer layer];
gradientLayer2.frame = CGRectMake(self.frame.size.width/2, 0, self.frame.size.width/2, self.frame.size.height);
gradientLayer2.colors = @[
(id)[UIColor greenColor].CGColor,
(id)[UIColor redColor].CGColor
];
[gradientLayer2 setStartPoint:CGPointMake(0.5, 0)];
[gradientLayer2 setEndPoint:CGPointMake(0.5, 1)];
[gradientLayer addSublayer:gradientLayer2];
[self.layer addSublayer:gradientLayer];
gradientLayer.mask = self.shapeLayer;
self.shapeLayer.strokeEnd = 0;
}
- (void)setPercent:(NSInteger)percent animated:(BOOL)animated {
[CATransaction begin];
[CATransaction setDisableActions:!animated];
[CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]];
[CATransaction setAnimationDuration:0.1];
self.shapeLayer.strokeEnd = percent/100.0;
[CATransaction commit];
self.percent = percent;
}
- (void)setPercent:(NSInteger)percent {
NSString *progress = [NSString stringWithFormat:@"%ld%%", percent];
label.text = progress;
}
@end

参考:1. https://www.ganlvji.com/gradient_circle_progress/
2. http://blog.it985.com/7654.html

人已赞赏
iOS文章

iOS废弃API取消出现Warning的方法

2020-3-5 1:09:35

iOS文章

iOS开发CALayer 相关

2020-3-5 3:09:32

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
有新消息 消息中心
搜索