iOS中利用CoreAnimation實(shí)現(xiàn)一個(gè)時(shí)間的進(jìn)度條效果
在iOS中實(shí)現(xiàn)進(jìn)度條通常都是通過不停的設(shè)置progress來完成的,這樣的進(jìn)度條適用于網(wǎng)絡(luò)加載(上傳下載文件、圖片等)。但是對于錄制視頻這樣的需求的話,如果是按照每秒來設(shè)置進(jìn)度的話,顯得有點(diǎn)麻煩,于是我就想直接用CoreAnimation來按時(shí)間做動(dòng)畫,只要設(shè)置最大時(shí)間,其他的就不用管了,然后在視頻暫停與繼續(xù)錄制時(shí),對動(dòng)畫進(jìn)行暫停和恢復(fù)即可。錄制視頻的效果如下:

你可以在這里下載demo
那么接下來就是如何用CoreAnimation實(shí)現(xiàn)一個(gè)進(jìn)度條控件了。
首先呢,讓我們創(chuàng)建一個(gè)繼承自CAShapeLayer的WKProgressBarLayer。
WKProgressBarLayer默認(rèn)自身的bounds就是整個(gè)進(jìn)度條的大小。
@interface WKProgressBarLayer : CAShapeLayer @end
為了方便外部調(diào)用,首先在WKProgressBarLayer.h中定義枚舉來表明動(dòng)畫的四個(gè)狀態(tài)
typedef NS_ENUM(NSInteger, WKAnimationStatus) {
WKAnimationStatusIdle,//空閑
WKAnimationStatusAnimating,//動(dòng)畫中
WKAnimationStatusPause,//暫停
WKAnimationStatusComplete//完成
};
接下來,定義外部調(diào)用的動(dòng)畫接口
@interface WKProgressBarLayer : CAShapeLayer @property (nonatomic, assign, readonly) WKAnimationStatus animatingStatus;//狀態(tài) /** 開始動(dòng)畫 @param duration 動(dòng)畫最大時(shí)長 */ - (void)beginAnimationWithDuration:(CGFloat)duration; /** 暫停 */ - (void)pauseAnimation; /** 恢復(fù) */ - (void)resumeAnimation; /** 重新開始動(dòng)畫 @param progress 從哪個(gè)進(jìn)度開始 @param duration 動(dòng)畫最大時(shí)長 */ - (void)restartAnimationWithProgress:(CGFloat)progress duration:(NSTimeInterval)duration; @end
然后,我們在.m實(shí)現(xiàn)核心的動(dòng)畫開始方法startAnimtionWithBeginProgress:duration:,詳細(xì)解釋見代碼
- (void)startAnimtionWithBeginProgress:(CGFloat)beginProgress duration:(NSTimeInterval)duration
{
[self reset];//重置動(dòng)畫
//設(shè)置path
UIBezierPath *fromPath = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, beginProgress * self.bounds.size.width, self.bounds.size.height)];;
UIBezierPath *toPath = [UIBezierPath bezierPathWithRect:self.bounds];
self.path = fromPath.CGPath;
//創(chuàng)建動(dòng)畫
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"path"];
animation.fromValue = (id)fromPath.CGPath;
animation.toValue = (id)toPath.CGPath;
animation.duration = duration;
[animation setValue:@1 forKey:@"progress"];//用于判斷是否是進(jìn)度動(dòng)畫
animation.delegate = self; //用于判斷動(dòng)畫結(jié)束
[self addAnimation:animation forKey:@"progressAnimation"];
self.path = toPath.CGPath;
}
然后呢,需要在動(dòng)畫的delegate與暫停、恢復(fù)動(dòng)畫的方法中分別修改動(dòng)畫的狀態(tài)
- (void)pauseAnimation
{
CFTimeInterval pausedTime = [self convertTime:CACurrentMediaTime() fromLayer:nil];
self.speed = 0.0;
self.timeOffset = pausedTime;
self.animatingStatus = WKAnimationStatusPause;
}
- (void)resumeAnimation
{
CFTimeInterval pausedTime = [self timeOffset];
self.speed = 1.0;
self.timeOffset = 0.0;
self.beginTime = 0.0;
CFTimeInterval timeSincePause = [self convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
self.beginTime = timeSincePause;
self.animatingStatus = WKAnimationStatusAnimating;
}
#pragma mark - CAAnimationDelegate
/* Called when the animation begins its active duration. */
- (void)animationDidStart:(CAAnimation *)anim
{
if (anim == [self animationForKey:@"progressAnimation"]) {//判斷進(jìn)度動(dòng)畫
self.animatingStatus = WKAnimationStatusAnimating;
}
}
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
if ([anim valueForKey:@"progress"] && flag == YES) {//判斷進(jìn)度動(dòng)畫
self.animatingStatus = WKAnimationStatusComplete;
}
}
至此,進(jìn)度條layer就完成了,現(xiàn)在創(chuàng)建一個(gè)控制器來做測試
首先在storyBoard擺上兩個(gè)按鈕,分別是開始與重置動(dòng)畫(界面搭建很簡單,詳情見demo)
然后在ViewDidLoad中添加progressLayer
- (void)viewDidLoad {
[super viewDidLoad];
WKProgressBarLayer *progressLayer = [[WKProgressBarLayer alloc] init];
progressLayer.frame = CGRectMake(100, 100, 200, 10);
[self.view.layer addSublayer:progressLayer];
self.progressLayer = progressLayer;
}
接下來,就是動(dòng)畫開始與重置響應(yīng)
- (IBAction)startOrPauseAction:(UIButton *)sender {
switch (self.progressLayer.animatingStatus) {
case WKAnimationStatusIdle:{
[self.progressLayer beginAnimationWithDuration:10];
}
break;
case WKAnimationStatusAnimating:{
[self.progressLayer pauseAnimation];
}
break;
case WKAnimationStatusPause:{
[self.progressLayer resumeAnimation];
}
break;
case WKAnimationStatusComplete:{
[self.progressLayer restartAnimationWithProgress:0 duration:10];
}
break;
default:
break;
}
sender.selected = !sender.selected;
}
- (IBAction)resetAction:(UIButton *)sender {
[self.progressLayer restartAnimationWithProgress:0 duration:10];
self.startOrPauseButton.selected = YES;
}
以上就是代碼主體了,接下來,讓我們看看效果

你可以在這里下載demo
總結(jié)
以上所述是小編給大家介紹的iOS中利用CoreAnimation實(shí)現(xiàn)一個(gè)時(shí)間的進(jìn)度條,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
- iOS實(shí)現(xiàn)步驟進(jìn)度條功能實(shí)例代碼
- 使用axios實(shí)現(xiàn)上傳圖片進(jìn)度條功能
- ios開發(fā)加載webview顯示進(jìn)度條實(shí)例
- iOS 進(jìn)度條、加載、安裝動(dòng)畫的簡單實(shí)現(xiàn)
- Android仿IOS ViewPager滑動(dòng)進(jìn)度條
- iOS實(shí)現(xiàn)帶動(dòng)畫的環(huán)形進(jìn)度條
- iOS快速實(shí)現(xiàn)環(huán)形漸變進(jìn)度條
- iOS中使用NSProgress類來創(chuàng)建UI進(jìn)度條的方法詳解
- IOS實(shí)現(xiàn)簡單的進(jìn)度條功能
- iOS中WKWebView仿微信加載進(jìn)度條
相關(guān)文章
iOS開發(fā)使用XML解析網(wǎng)絡(luò)數(shù)據(jù)
XML解析其實(shí)這個(gè)概念出現(xiàn)了算夠久了,以前javaweb什么到處都在用。這邊我們主要大致介紹下,然后在在ios編程如何使用。2016-02-02
iOS App開發(fā)中Objective-C使用正則表達(dá)式進(jìn)行匹配的方法
這篇文章主要介紹了iOS App開發(fā)中Objective-C使用正則表達(dá)式進(jìn)行匹配的方法,文中舉了在iOS中驗(yàn)證用戶郵箱與手機(jī)號(hào)的例子,非常實(shí)用,匹配需要的朋友可以參考下2016-05-05
iOS對數(shù)組進(jìn)行排序的實(shí)例代碼
本文通過實(shí)例代碼給大家講解了ios對數(shù)組進(jìn)行排序的實(shí)例方法,非常不錯(cuò),具有參考借鑒價(jià)值,需要的的朋友參考下吧2017-08-08

