iOS中利用CoreAnimation实现一个时间的进度条效果
程序员文章站
2023-12-20 23:53:28
在ios中实现进度条通常都是通过不停的设置progress来完成的,这样的进度条适用于网络加载(上传下载文件、图片等)。但是对于录制视频这样的需求的话,如果是按照每秒来设置...
在ios中实现进度条通常都是通过不停的设置progress来完成的,这样的进度条适用于网络加载(上传下载文件、图片等)。但是对于录制视频这样的需求的话,如果是按照每秒来设置进度的话,显得有点麻烦,于是我就想直接用coreanimation来按时间做动画,只要设置最大时间,其他的就不用管了,然后在视频暂停与继续录制时,对动画进行暂停和恢复即可。录制视频的效果如下:
你可以在这里下载demo
那么接下来就是如何用coreanimation实现一个进度条控件了。
首先呢,让我们创建一个继承自cashapelayer的wkprogressbarlayer。
wkprogressbarlayer默认自身的bounds就是整个进度条的大小。
@interface wkprogressbarlayer : cashapelayer @end
为了方便外部调用,首先在wkprogressbarlayer.h中定义枚举来表明动画的四个状态
typedef ns_enum(nsinteger, wkanimationstatus) { wkanimationstatusidle,//空闲 wkanimationstatusanimating,//动画中 wkanimationstatuspause,//暂停 wkanimationstatuscomplete//完成 };
接下来,定义外部调用的动画接口
@interface wkprogressbarlayer : cashapelayer @property (nonatomic, assign, readonly) wkanimationstatus animatingstatus;//状态 /** 开始动画 @param duration 动画最大时长 */ - (void)beginanimationwithduration:(cgfloat)duration; /** 暂停 */ - (void)pauseanimation; /** 恢复 */ - (void)resumeanimation; /** 重新开始动画 @param progress 从哪个进度开始 @param duration 动画最大时长 */ - (void)restartanimationwithprogress:(cgfloat)progress duration:(nstimeinterval)duration; @end
然后,我们在.m实现核心的动画开始方法startanimtionwithbeginprogress:duration:,详细解释见代码
- (void)startanimtionwithbeginprogress:(cgfloat)beginprogress duration:(nstimeinterval)duration { [self reset];//重置动画 //设置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; //创建动画 cabasicanimation *animation = [cabasicanimation animationwithkeypath:@"path"]; animation.fromvalue = (id)frompath.cgpath; animation.tovalue = (id)topath.cgpath; animation.duration = duration; [animation setvalue:@1 forkey:@"progress"];//用于判断是否是进度动画 animation.delegate = self; //用于判断动画结束 [self addanimation:animation forkey:@"progressanimation"]; self.path = topath.cgpath; }
然后呢,需要在动画的delegate与暂停、恢复动画的方法中分别修改动画的状态
- (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"]) {//判断进度动画 self.animatingstatus = wkanimationstatusanimating; } } - (void)animationdidstop:(caanimation *)anim finished:(bool)flag { if ([anim valueforkey:@"progress"] && flag == yes) {//判断进度动画 self.animatingstatus = wkanimationstatuscomplete; } }
至此,进度条layer就完成了,现在创建一个控制器来做测试
首先在storyboard摆上两个按钮,分别是开始与重置动画(界面搭建很简单,详情见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; }
接下来,就是动画开始与重置响应
- (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
总结
以上所述是小编给大家介绍的ios中利用coreanimation实现一个时间的进度条,希望对大家有所帮助