美文网首页
简单扇形动画的应用

简单扇形动画的应用

作者: 码农耕 | 来源:发表于2019-06-14 17:53 被阅读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献上

    相关文章

      网友评论

          本文标题:简单扇形动画的应用

          本文链接:https://www.haomeiwen.com/subject/hewpfctx.html