今天項(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