在iOS中实现进度条通常都是通过不停的设置的进步来完成的,这样的进度条适用于网络加载(上传下载文件,图片等)。但是对于录制视频这样的需求的话,如果是按照每秒来设置进度的话,显得有点麻烦,于是我就想直接用CoreAnimation来按时间做动画,只要设置最大时间,其他的就不用管了,然后在视频暂停与继续录制时,对动画进行暂停和恢复即可。录制视频的效果如下:
你可以在这里下载演示
那么接下来就是如何用CoreAnimation实现一个进度条控件了。
首先呢,让我们创建一个继承自CAShapeLayer的WKProgressBarLayer。
WKProgressBarLayer默认自身的界限就是整个进度条的大小。
@ interface WKProgressBarLayer: CAShapeLayer @end
,为了方便外部调用,首先在WKProgressBarLayer.h中定义枚举来表明动画的四个状态
typedef NS_ENUM (NSInteger WKAnimationStatus) { WKAnimationStatusIdle,//空闲 WKAnimationStatusAnimating,//动画中 WKAnimationStatusPause,//暂停 WKAnimationStatusComplete//完成};
,接下来,定义外部调用的动画接口
@ interface WKProgressBarLayer: CAShapeLayer @ property(原子、分配、只读的)WKAnimationStatus animatingStatus;//状态/* * 开始动画 @param时间动画最大时长 */- (void) beginAnimationWithDuration: (CGFloat)持续时间;/* * 暂停 */- (void) pauseAnimation;/* * 恢复 */- (void) resumeAnimation;/* * 重新开始动画 @param进展从哪个进度开始 @param时间动画最大时长 */- (void) restartAnimationWithProgress: (CGFloat)进展:持续时间(NSTimeInterval)持续时间; @end
,然后,我们在m实现核心的动画开始方法startAnimtionWithBeginProgress:持续时间:,详细解释见代码
- (void) startAnimtionWithBeginProgress: (CGFloat) beginProgress:持续时间(NSTimeInterval)持续时间 { (自动复位);//重置动画//设置的道路 UIBezierPath * fromPath=[UIBezierPath bezierPathWithRect: CGRectMake (0, 0, beginProgress * self.bounds.size。宽度,self.bounds.size.height)];; UIBezierPath * toPath=[UIBezierPath bezierPathWithRect self.bounds):; 自我。路径=fromPath.CGPath;//创建动画 CABasicAnimation *动画=[CABasicAnimation animationWithKeyPath: @“路径”); fromPath.CGPath animation.fromValue=https://www.yisu.com/zixun/(id); 动画。toPath.CGPath toValue=(id); 动画。时间=时间; 【动画setValue: @1 forKey: @“进步”);//用于判断是否是进度动画 animation.delegate=自我;//用于判断动画结束 【自我addAnimation:动画forKey: @“progressAnimation”); 自我。路径=toPath.CGPath; }
,然后呢,需要在动画的委托与暂停,恢复动画的方法中分别修改动画的状态
- (void) pauseAnimation { CFTimeInterval pausedTime=[自我convertTime: CACurrentMediaTime () fromLayer: nil); 自我。速度=0.0; 自我。timeOffset=pausedTime; 自我。animatingStatus=WKAnimationStatusPause; } - (void) resumeAnimation { CFTimeInterval pausedTime=(自我timeOffset); 自我。速度=1.0; 自我。timeOffset=0.0; 自我。beginTime=0.0; CFTimeInterval timeSincePause=[自我convertTime: CACurrentMediaTime () fromLayer: nil) - pausedTime; 自我。beginTime=timeSincePause; 自我。animatingStatus=WKAnimationStatusAnimating; } # pragma马克- CAAnimationDelegate/*动画开始时调用活动持续时间。*/- (void) animationDidStart: (CAAnimation *) { 如果动画==[自我animationForKey: @ progressAnimation "]){//判断进度动画 自我。animatingStatus=WKAnimationStatusAnimating; } } - (void) animationDidStop: (CAAnimation *)动画完成:BOOL国旗 { 如果([动物valueForKey: @“进步”),,标志==YES){//判断进度动画 自我。animatingStatus=WKAnimationStatusComplete; } }
,至此,进度条层就完成了,现在创建一个控制器来做测试
首先在故事板摆上两个按钮,分别是开始与重置动画(界面搭建很简单,详情见演示)
然后在ViewDidLoad中添加progressLayer