簡單扇形動畫的應(yīng)用

今天項(xiàng)目遇到一個(gè)場景:播放PPT給用戶看。功能已經(jīng)做好了,但是每次測試都很痛苦,這個(gè)PPT要播放多久?。窟€有多少頁?。?br> 基于這個(gè)問題做了一個(gè)扇形的頁面進(jìn)度展示:
可以動態(tài)的展示PPT當(dāng)前的頁碼(總進(jìn)度)
可以動態(tài)的展示每一頁P(yáng)PT的進(jìn)度
實(shí)現(xiàn)原理:
根據(jù)UIBezierPath生成一個(gè)layer,再給這個(gè)layer添加一個(gè)進(jìn)度動畫(模擬每一張PPT的播放進(jìn)度);
在上面蓋一個(gè)Label,展示PPT頁碼進(jìn)度

OK,please show me code!

根據(jù)UIBezierPath路徑生成layer:

UIBezierPath *bgPath = [UIBezierPath bezierPathWithArcCenter:centerPoint
                                                          radius:bgRadius
                                                      startAngle:-M_PI_2
                                                        endAngle:M_PI_2 * 3
                                                       clockwise:YES];
    
    CAShapeLayer *_bgCircleLayer  = [CAShapeLayer layer];
    _bgCircleLayer.fillColor      = [UIColor clearColor].CGColor;
    _bgCircleLayer.strokeColor    = [UIColor lightGrayColor].CGColor;
    _bgCircleLayer.strokeStart    = 0.0f;
    _bgCircleLayer.strokeEnd      = 1.0f;
    _bgCircleLayer.zPosition      = 1;
    _bgCircleLayer.lineWidth      = bgRadius * 2.0f;
    _bgCircleLayer.path           = bgPath.CGPath;

添加動畫:

    CABasicAnimation *animation   = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    animation.duration            = [self.timeArray[self.currentIndex]integerValue];
    animation.fromValue           = @0.0f;
    animation.toValue             = @1.0f;
    animation.timingFunction      = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];// 動畫速度類型
    animation.removedOnCompletion = YES;
    animation.delegate            = self;
    [_bgCircleLayer addAnimation:animation forKey:@"circleAnimation"];

暫停播放PPT:

    // 當(dāng)前時(shí)間(暫停時(shí)的時(shí)間)
    // CACurrentMediaTime() 是基于內(nèi)建時(shí)鐘的,能夠更精確更原子化地測量,并且不會因?yàn)橥獠繒r(shí)間變化而變化(例如時(shí)區(qū)變化、夏時(shí)制、秒突變等),但它和系統(tǒng)的uptime有關(guān),系統(tǒng)重啟后CACurrentMediaTime()會被重置
    CFTimeInterval pauseTime = [self.circleView.layer convertTime:CACurrentMediaTime() fromLayer:nil];
    // 停止動畫
    self.circleView.layer.speed = 0;
    // 動畫的位置(動畫進(jìn)行到當(dāng)前時(shí)間所在的位置,如timeOffset=1表示動畫進(jìn)行1秒時(shí)的位置)
    self.circleView.layer.timeOffset = pauseTime;

繼續(xù)播放PPT:

    // 動畫的暫停時(shí)間
    CFTimeInterval pausedTime = self.circleView.layer.timeOffset;
    // 動畫初始化
    self.circleView.layer.speed = 1;
    self.circleView.layer.timeOffset = 0;
    self.circleView.layer.beginTime = 0;
    // 程序到這里,動畫就能繼續(xù)進(jìn)行了,但不是連貫的,而是動畫在背后默默“偷跑”的位置,如果超過一個(gè)動畫周期,則是初始位置
    // 當(dāng)前時(shí)間(恢復(fù)時(shí)的時(shí)間)
    CFTimeInterval continueTime = [self.circleView.layer convertTime:CACurrentMediaTime() fromLayer:nil];
    // 暫停到恢復(fù)之間的空檔
    CFTimeInterval timePause = continueTime - pausedTime;
    // 動畫從timePause的位置從動畫頭開始
    self.circleView.layer.beginTime = timePause;

每一張PPT時(shí)長不一樣,設(shè)置動畫的播放時(shí)間不一樣。
效果圖.gif

Demo獻(xiàn)上

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容