前言
最近由于要给APP更新UI,然后UIDesigner为了”尝鲜”,给我一些新的界面设计,所以我这里也不得不再来造些另外的轮子。如果对您有帮助,麻烦Github给个star
这里先来看下今天要造的轮子
没错,就是上边的进度条。
实现
先说下思路(采用的是使用MASK遮罩,然后改变底层OrangeColorLayer长度,以达到进度条长度变化的思路)
- 首先,我们创建一个新的类,
继承自UIView
,然后,我们采用Core Graphics
框架和UIBezierPath类
来实现中间的进度条样式。先来分析下进度条,可以看出来,进度条内部,有两种颜色:橙色的TintColor
,DarkGray的进度达不到的进度条颜色
,然后,进度条背景色lightDarkColor
,和最上层圆形中的小圆点
。 - 我这里的进度条,实现发方法是采用4层layer来实现:最底层,绘制
DarkGray颜色的进度条
,再往上一层,设置有颜色的一层layer,通过改变该层layer的宽度,已达到有颜色进度条的长度变化,再上层,是一个中间进度条轮廓透明,周围是lightGrayColor背景色的遮罩View
,最上层,是几个进度条内部小圆的layer。采用的是使用MASK遮罩,然后改变底层OrangeColorLayer长度,以达到进度条长度变化的思路
- 首先,我们创建一个新的类,
这里代码
1.先看下暴露出来的API接口@interface RRMyMaterialProgressBar : UIView
//一共项数
//@property (nonatomic,assign) CGFloat totalStepsCounts;@property (nonatomic,strong) CAShapeLayer *firstArc;
@property (nonatomic,strong) CAShapeLayer *secondArc;
@property (nonatomic,strong) CAShapeLayer *thirdArc;
@property (nonatomic,strong) CAShapeLayer *forthArc;
//当前进度
@property (nonatomic,assign) CGFloat currentPercentage;
//渲染颜色
//@property (nonatomic,strong) UIColor *progressBarTintColor;(instancetype)initWithFrame:(CGRect)frame totalStepsCounts:(CGFloat)steps progressBarTintColor:(UIColor *)tintClr;
@end
PS:
这里是有一些问题的,最开始的时候,我是在drawRect
方法中实现的,然后把总共的圆形个数,和进度条的渲染颜色都作为了外部属性,也是能实现的,但是:有些问题:考虑下我们的使用场景:一般我们都是在外层VC的viewWillAppear或者viewDidLoad
方法中设置这个progressBar的进度,但是!如果在drawRect
方法中实现的话,此时,内部的各个layer都还没有初始化,全部都是nil,如果在viewDidAppear
方法中设置的话,会有一个BUG:刚进到页面内的时候,会看到进度条的进度是100%的,(因为默认创建ColorLayer的时候是设置的整个Frame的),然后,调用外层viewDidAppear
方法设置进度条的进度Layer长度,此时,进度条才会又从头开始显示。这么一来,用户体验就不是太好了。
所以,我又优化了一下:progressBarView 初始化的时候,就来绘制这些内层layer,以此来保证外部VC调用viewWillAppear或者viewDidLoad
方法的时候,内层progressBar内的各个实例都已经ALLOC,并且可以设置他们。(所以,以前的totalStepsCounts和progressBarTintColor
都可以设置为私有变量),然后我们直接在初始化方法中传入参数以赋值。
1 | #import "RRMyMaterialProgressBar.h" |
另外
整个进度条并不是圆形是环形的,如果有UI需求,我们可以通过设置API接口中的四个shapeLayer的fillColor
值来改变内部小圆的颜色的1
self.forthArc.fillColor = [UIColor yourWantedColor].CGColor;
这里有些参考资料
都是关于view中间镂空周围不是空的