在很多時候我們都需要使用進度條來幫助我們檢視進度,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。
就獲得了一個漸變圓環。
底軌圓環:
我們上面建立的軌道隻有進度條,沒有底軌條。為了美觀,我們可以加入底軌,也就是相當于建立一個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的使用還在初步入門階段,還望各位大佬指正。