iOS手把手教你實現圓形進度條
引言
在做音頻項目的時候,播放音頻需要顯示圓形進度條。今天,教大家如何簡單地實現進度條效果!
其實,實現這種效果并不困難。前提是需要了解UIBezierPath,如果未接觸過,可以先閱讀筆者在很久以前所寫過的一篇文章:UIBezierPath精講
當然,之前在實現 高級動畫-圓形樹展開、收起動畫 一文中教了大家如何實現漸變圓形進度條,那是采用mask來實現的。
不過,今天教大家做的效果,并沒有使用mask,而是直接使用UIBezierPath來實現。
效果圖

實現原理
- 第一步:添加背景灰色圓形圈圈,畫筆色為灰色,內容色為透明。如此一來,中間的圖片就可以看見了
- 第二步:再添加表示進度的藍色圓形圈圈,與第一步一樣,只是設置畫筆顏色為藍色
- 第三步:由于bezierpath的圓形起點是M 2 PI,這與最終的效果不一樣,因此需要額外處理一下。所以,將整體的transform旋轉-M 2 PI,這樣進度起點就是從12點鐘方向開始的了,與效果圖一樣。但是,整體旋轉后,圖片就不是正立了,因此需要讓圖片控件的transform旋轉M 2 PI,這樣就是最終的效果了
代碼實現
首先,我們需要新建一個HYBCircleProgressView類,這樣才能對整體旋轉!
@interfaceHYBCircleProgressView: UIView
// 設置圖片
- (void)setImageURL:(NSString *)url;
// 更新進度
- (void)updateProgressWithNumber:(NSUInteger)number;
@end
</code></pre>
創建圖片:
CGRect frame = self.frame;
self.layer.cornerRadius = frame.size.width / 2;
self.layer.masksToBounds = YES;
self.imageView = [[UIImageView alloc]initWithFrame:self.bounds];
[selfaddSubview:self.imageView];
第一步:添加灰色圓環
首先,創建CAShapeLayer對象,然后生成圓形path,并設置畫筆顏色為灰色,線寬(圓環的寬)為2,而內容填充色設置為透明色,然后將此層添加到self.layer上:
self.outLayer = [CAShapeLayer layer];
CGRect rect = {kLineWidth / 2, kLineWidth / 2,
frame.size.width - kLineWidth, frame.size.height - kLineWidth};
UIBezierPath *path = [UIBezierPathbezierPathWithOvalInRect:rect];
self.outLayer.strokeColor = [UIColor lightGrayColor].CGColor;
self.outLayer.lineWidth = kLineWidth;
self.outLayer.fillColor = [UIColor clearColor].CGColor;
self.outLayer.lineCap = kCALineCapRound;
self.outLayer.path = path.CGPath;
[self.layeraddSublayer:self.outLayer];
第二步:添加藍色進度圓環
這一步與第一步相當,只是修改畫筆顏色為藍色而已。所使用的path與第一步的是一樣的:
self.progressLayer = [CAShapeLayer layer];
self.progressLayer.fillColor = [UIColor clearColor].CGColor;
self.progressLayer.strokeColor = [UIColor blueColor].CGColor;
self.progressLayer.lineWidth = kLineWidth;
self.progressLayer.lineCap = kCALineCapRound;
self.progressLayer.path = path.CGPath;
[self.layeraddSublayer:self.progressLayer];
到這一步,可以看到的效果是這樣的:

從效果圖可以看到,圖片是正立的,但是進度條的起點是從3點鐘方向開始的,也就是M 2 PI開始順時鐘方向變化。可我們希望是從12點鐘方向開始順時鐘變化的,那么解決辦法就是旋轉!看第三步。
第三步:旋轉以調整進度起點
將整體旋轉-90度,使進度起點為12點鐘的位置:
self.transform = CGAffineTransformMakeRotation(-M_PI_2);
此時效果是這樣的:

圖片也跟著旋轉了,這不是我們要的效果啊。那么怎么辦呢?同樣的道理,將圖片控件再旋轉90度即可:
self.imageView.transform = CGAffineTransformMakeRotation(M_PI_2);
如何動畫調整進度
調整這個進度,其中就是調整strokeEnd,這個屬性是支持隱式動畫的:
- (void)updateProgressWithNumber:(NSUInteger)number {
[CATransaction begin];
[CATransactionsetAnimationTimingFunction:[CAMediaTimingFunctionfunctionWithName:kCAMediaTimingFunctionEaseIn]];
[CATransactionsetAnimationDuration:0.5];
self.progressLayer.strokeEnd = number / 100.0;
[CATransaction commit];
}
</code></pre>
小結
請大家不要找我要完整的demo,這已經是所有代碼了,只不過是沒有將構造方式放出來而已!
這里是巧妙地利用旋轉來調整起點,又利用貝塞爾曲線來實現所謂地鏤空圖!看到這里,是不是覺得很簡單呢?其實也就那么回事!
來自: http://www.henishuo.com/circle-progress-bar/