[iOS开发]用CAShapeLayer实现圆形进度条

在很多时候我们都需要使用进度条来帮助我们查看进度,iOS框架自带了progressView来供我们使用。可是,如果我们需要圆形的⭕️进度条,那么就需要我们自定义了。嘿嘿,下面来看看怎么搞。😁

基本需求

先创建一个继承自UIView的自定义View。
里面有一个这样的方法:

// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
	...
}

定义文件里面加入控制进度的东西:

@property (nonatomic, assign) float progress;
- (void)changeProgress:(float)progress;

在里面实现:

CGPoint center = CGPointMake(self.bounds.size.width / 2, self.bounds.size.width / 2);
CGFloat radius = self.bounds.size.width / 2 - 7 / 2;
//半径画出来的圆为路径中心的圆
CGFloat startA = - M_PI_2;  //设置进度条起点位置
CGFloat endA = -M_PI_2 + M_PI * 2 * _progress;  //设置进度条终点位置

//获取环形路径(画一个圆形,填充色透明,设置线框宽度为某值,这样就获得了一个环形)
_progressLayer = [CAShapeLayer layer];
//创建一个track shape layer
_progressLayer.frame = self.bounds;
_progressLayer.fillColor = [[UIColor clearColor] CGColor];
//填充色为无色
_progressLayer.strokeColor = [[UIColor redColor] CGColor];
//指定path的渲染颜色,这里可以设置任意不透明颜色
_progressLayer.opacity = 1; //背景颜色的透明度
_progressLayer.lineWidth = 7;//线的宽度
//_progressLayer.lineCap = kCALineCapButt;
//指定线的边缘类型
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:startA endAngle:endA clockwise:YES];//上面说明过了用来构建圆形
_progressLayer.path = [path CGPath];
[self.layer addSublayer:_progressLayer];

将进度设为不同值,看看效果:
在这里插入图片描述
请添加图片描述
可以发现我们的需求已经大致达成了,我们是使用贝塞尔曲线画出了圆弧,再将进度条layer的路径设置为曲线路径就完成了基本需求。

进阶需求

我们还可以同通过使用一系列属性,对这个进度条的各个方面进行一些改进:

_progressLayer.lineCap = kCALineCapRound;
//指定线的边缘是圆的

圆角进度条:

在这里插入图片描述

虚线进度条:

_progressLayer.lineDashPattern = @[@10, @5];
//按照数组中的长度依次打断

效果:
在这里插入图片描述

渐变色进度条:

可以生成一个单一底色:

CALayer *gradientLayer = [CALayer layer];
gradientLayer.frame = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.width);
[gradientLayer setBackgroundColor:[UIColor redColor].CGColor];

也可以在上面添加渐变图层:

//左侧渐变色
CAGradientLayer *leftLayer = [CAGradientLayer layer];
leftLayer.frame = CGRectMake(0, 0, self.bounds.size.width / 2, self.bounds.size.width);    // 分段设置渐变色
leftLayer.locations = @[@0.2, @0.8, @1];
leftLayer.colors = @[(id)[UIColor greenColor].CGColor, (id)[UIColor yellowColor].CGColor];
[gradientLayer addSublayer:leftLayer];

//右侧渐变色
CAGradientLayer *rightLayer = [CAGradientLayer layer];
rightLayer.frame = CGRectMake(self.bounds.size.width / 2, 0, self.bounds.size.width / 2, self.bounds.size.height);
rightLayer.locations = @[@0.2, @0.8, @1];
rightLayer.colors = @[(id)[UIColor redColor].CGColor, (id)[UIColor yellowColor].CGColor];
[gradientLayer addSublayer:rightLayer];

图层效果:
在这里插入图片描述
创造出了一个三色渐变图层。为了让进度条颜色变成渐变,我们需要使用:

[gradientLayer setMask:_progressLayer];
//用progressLayer来截取渐变层

截取过程是怎么样呢?下面我就使用Keynote为大家演示一下。
在这里插入图片描述
相当于有两个图形:
在这里插入图片描述

截获操作相当于使用Keynote多图形操作中的交叉:
在这里插入图片描述
以小圆图形的形状截取大底色:
在这里插入图片描述
就获得了带有渐变的圆形轨道。
再将截获的圆轨加到view。

[self.layer addSublayer:gradientLayer];

在这里插入图片描述
就获得了一个渐变圆环。

底轨圆环:

我们上面创建的轨道只有进度条,没有底轨条。为了美观,我们可以加入底轨,也就是相当于创建一个100%进度的底色进度条,再将我们的进度条加到轨道层上面就好啦。

_progressLayer2 = [CAShapeLayer layer];
_progressLayer2.frame = self.bounds;
_progressLayer2.fillColor = [[UIColor clearColor] CGColor];
_progressLayer2.strokeColor = [[UIColor colorWithWhite:0.9 alpha:1] CGColor];
_progressLayer2.opacity = 1;
_progressLayer2.lineWidth = 7;//线的宽度
UIBezierPath *path2 = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:startA endAngle:-M_PI_2 + M_PI * 2 clockwise:YES];
_progressLayer2.path = [path2 CGPath];
[self.layer addSublayer:_progressLayer2];

[_progressLayer2 addSublayer:gradientLayer];

实现效果:
在这里插入图片描述

动态进度条:

runloop中使用计时器控制进度,就可以轻松实现进度条的动画啦

- (void)changeProgress:(float)progress {
    _progress = progress;
    [self setNeedsDisplay];
}

小结:

以上就是对进度条的一个使用心得。对layer的使用还在初步入门阶段,还望各位大佬指正。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
iOS中使用CAShapeLayer进行绘图是一种非常方便和高效的方法。CAShapeLayer是一个类似于CALayer的图层,它可以用来绘制矢量图形。使用CAShapeLayer可以避免使用Core Graphics绘图时可能遇到的一些性能问题。 下面是一个简单的例子,演示如何使用CAShapeLayer绘制一个圆形: 1. 创建CAShapeLayer对象 ``` CAShapeLayer *circleLayer = [CAShapeLayer layer]; ``` 2. 设置CAShapeLayer的属性 ``` // 设置填充颜色 circleLayer.fillColor = [UIColor clearColor].CGColor; // 设置描边颜色 circleLayer.strokeColor = [UIColor redColor].CGColor; // 设置描边宽度 circleLayer.lineWidth = 5; // 设置路径 CGFloat radius = 50; circleLayer.path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, radius*2, radius*2)].CGPath; // 设置位置 circleLayer.position = CGPointMake(100, 100); ``` 3. 将CAShapeLayer添加到视图中 ``` [self.view.layer addSublayer:circleLayer]; ``` 这样,一个圆形就被绘制出来了。 除了绘制基本图形,还可以通过CAShapeLayer绘制复杂的路径,例如: ``` CAShapeLayer *pathLayer = [CAShapeLayer layer]; UIBezierPath *path = [UIBezierPath bezierPath]; [path moveToPoint:CGPointMake(100, 100)]; [path addLineToPoint:CGPointMake(200, 200)]; [path addLineToPoint:CGPointMake(100, 300)]; [path addLineToPoint:CGPointMake(0, 200)]; [path closePath]; pathLayer.path = path.CGPath; pathLayer.strokeColor = [UIColor redColor].CGColor; pathLayer.fillColor = [UIColor clearColor].CGColor; pathLayer.lineWidth = 5; [self.view.layer addSublayer:pathLayer]; ``` 这个例子中,我们使用UIBezierPath创建了一个具有四个顶点的路径,并将其添加到CAShapeLayer中,然后将CAShapeLayer添加到视图中。 使用CAShapeLayer进行绘图非常方便和高效。希望这篇回答对你有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值