今天项目遇到一个场景:播放PPT给用户看。功能已经做好了,但是每次测试都很痛苦,这个PPT要播放多久啊?还有多少页啊?
基于这个问题做了一个扇形的页面进度展示:
可以动态的展示PPT当前的页码(总进度)
可以动态的展示每一页PPT的进度
实现原理:
根据UIBezierPath生成一个layer,再给这个layer添加一个进度动画(模拟每一张PPT的播放进度);
在上面盖一个Label,展示PPT页码进度
OK,please show me code!
根据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:
// 当前时间(暂停时的时间)
// CACurrentMediaTime() 是基于内建时钟的,能够更精确更原子化地测量,并且不会因为外部时间变化而变化(例如时区变化、夏时制、秒突变等),但它和系统的uptime有关,系统重启后CACurrentMediaTime()会被重置
CFTimeInterval pauseTime = [self.circleView.layer convertTime:CACurrentMediaTime() fromLayer:nil];
// 停止动画
self.circleView.layer.speed = 0;
// 动画的位置(动画进行到当前时间所在的位置,如timeOffset=1表示动画进行1秒时的位置)
self.circleView.layer.timeOffset = pauseTime;
继续播放PPT:
// 动画的暂停时间
CFTimeInterval pausedTime = self.circleView.layer.timeOffset;
// 动画初始化
self.circleView.layer.speed = 1;
self.circleView.layer.timeOffset = 0;
self.circleView.layer.beginTime = 0;
// 程序到这里,动画就能继续进行了,但不是连贯的,而是动画在背后默默“偷跑”的位置,如果超过一个动画周期,则是初始位置
// 当前时间(恢复时的时间)
CFTimeInterval continueTime = [self.circleView.layer convertTime:CACurrentMediaTime() fromLayer:nil];
// 暂停到恢复之间的空档
CFTimeInterval timePause = continueTime - pausedTime;
// 动画从timePause的位置从动画头开始
self.circleView.layer.beginTime = timePause;
每一张PPT时长不一样,设置动画的播放时间不一样。
![](https://img.haomeiwen.com/i1725708/d0790eda146cefcd.gif)
网友评论