溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

iOS中利用CoreAnimation實現(xiàn)一個時間的進度條效果

發(fā)布時間:2020-09-29 08:39:00 來源:腳本之家 閱讀:216 作者:pretty guy 欄目:移動開發(fā)

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

iOS中利用CoreAnimation實現(xiàn)一個時間的進度條效果

你可以在這里下載demo

那么接下來就是如何用CoreAnimation實現(xiàn)一個進度條控件了。

首先呢,讓我們創(chuàng)建一個繼承自CAShapeLayer的WKProgressBarLayer。

WKProgressBarLayer默認自身的bounds就是整個進度條的大小。

@interface WKProgressBarLayer : CAShapeLayer
@end

 為了方便外部調(diào)用,首先在WKProgressBarLayer.h中定義枚舉來表明動畫的四個狀態(tài)

typedef NS_ENUM(NSInteger, WKAnimationStatus) {
 WKAnimationStatusIdle,//空閑
 WKAnimationStatusAnimating,//動畫中
 WKAnimationStatusPause,//暫停
 WKAnimationStatusComplete//完成
};

 接下來,定義外部調(diào)用的動畫接口

@interface WKProgressBarLayer : CAShapeLayer
@property (nonatomic, assign, readonly) WKAnimationStatus animatingStatus;//狀態(tài)
/**
 開始動畫
 @param duration 動畫最大時長
 */
- (void)beginAnimationWithDuration:(CGFloat)duration;
/**
 暫停
 */
- (void)pauseAnimation;
/**
 恢復(fù)
 */
- (void)resumeAnimation;
/**
 重新開始動畫
 @param progress 從哪個進度開始
 @param duration 動畫最大時長
 */
- (void)restartAnimationWithProgress:(CGFloat)progress duration:(NSTimeInterval)duration;
@end

 然后,我們在.m實現(xiàn)核心的動畫開始方法startAnimtionWithBeginProgress:duration:,詳細解釋見代碼

- (void)startAnimtionWithBeginProgress:(CGFloat)beginProgress duration:(NSTimeInterval)duration
{
 [self reset];//重置動畫
 //設(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)建動畫
 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; //用于判斷動畫結(jié)束
 [self addAnimation:animation forKey:@"progressAnimation"];
 self.path = toPath.CGPath;
}

 然后呢,需要在動畫的delegate與暫停、恢復(fù)動畫的方法中分別修改動畫的狀態(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"]) {//判斷進度動畫
  self.animatingStatus = WKAnimationStatusAnimating;
 }
}
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
 if ([anim valueForKey:@"progress"] && flag == YES) {//判斷進度動畫
  self.animatingStatus = WKAnimationStatusComplete;
 }
}

 至此,進度條layer就完成了,現(xiàn)在創(chuàng)建一個控制器來做測試

首先在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;
}

 接下來,就是動畫開始與重置響應(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;
}

 以上就是代碼主體了,接下來,讓我們看看效果

iOS中利用CoreAnimation實現(xiàn)一個時間的進度條效果

你可以在這里下載demo

總結(jié)

以上所述是小編給大家介紹的iOS中利用CoreAnimation實現(xiàn)一個時間的進度條,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對億速云網(wǎng)站的支持!

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI