Swift用贝塞尔曲线做弧形进度条(Mac版)
项目需求,需要通过类似弧形进度条展示某项数据,在简单查阅后,根据几个作者的iOS版本进行修改,完成了Mac版本。利用贝塞尔曲线,不很复杂。
1. 主要思路
- 绘制背景layer层,设置lineWidth,fillColor,strokeColor与lineCap
- 为layer添加贝塞尔曲线路径
- 绘制前置进度条层,除strokeColor外均与背景layer相同
- 根据需求,暴露设置百分比的方法,同时会根据百分比改变进度条颜色。
2. 具体实现
2.1 背景layer层绘制
背景是一个CAShapeLayer,这是常规思路,为这个layer设置各种参数,其中lineCap是指路径起点终点的样式,默认.butt,我选择了.round
1 | let backgroundLayer = CAShapeLayer() |
2.2 添加贝塞尔曲线路径
参考的iOS代码里,UIBezierPath初始化时可以使用acr的一系列参数,但不确定是UIBezierPath和NSBezierPath之间的差别还是Swift5之后的变化,不过可以使用appendArc方法。1
2
3
4
5func appendArc(withCenter center: NSPoint,
radius: CGFloat,
startAngle: CGFloat,
endAngle: CGFloat,
closewise:bool)
其中,center是圆心,radius是半径,startAngle与endAngle分别是起点终点的角度, closewise为是否顺时针,也就是从开始到结束角度,选择哪一段。
圆心和半径都是根据具体需求进行设置,由于我需要的是圆弧,所以圆心设在了frame外面,半径需要减去1/2 * lineWidth。关于起始角度,开始参考了别人blog里的这张图
我需要的大概是图中标黑的那一段,所以使用的是弧度制,开始角度为 1.25 pi , 结束角度为 1.75 pi , 但得到的圆弧总是一个整圆。后来经过尝试,改成了角度制,开始角度为145度,结束角度为45度,才得到需要的圆弧。所以这个角度不应该是上图中的取法,而是逆时针与x轴正方向的夹角。
所以我的代码如下
1 | let center = CGPoint(x: rect.size.width/2, y: -rect.size.width/2) |
2.3
前置进度条层foreLayer,设置与backgroundLayer完全一样,也许次添加上述的贝塞尔曲线,唯一区别在需要设置strokeEnd的值,是描边的进度,用来体现进度条的效果,并根据不同进度显示不同strokeColor,设置颜色和strokeEnd的值的方法暴露为public1
2
3
4
5
6
7
8
9
10foreLayer?.lineCap = .round
foreLayer?.path = bezierPath.cgPath
foreLayer?.strokeStart = 0
foreLayer?.strokeEnd = 0.5
backgroundLayer.addSublayer(foreLayer!)
self.layer = backgroundLayer
1 |
|
3 实际效果
参考链接
原文链接 http://blog.wuqingzhe.cn/2020/11/23/Swift用贝塞尔曲线做弧形进度条(Mac版)/