简单扇形动画的应用

2019-06-14  本文已影响0人  码农耕

今天项目遇到一个场景:播放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时长不一样,设置动画的播放时间不一样。 效果图.gif

Demo献上

上一篇 下一篇

猜你喜欢

热点阅读