美文网首页iOS常用
iOS 用CAReplicatorLayer做点加载动画

iOS 用CAReplicatorLayer做点加载动画

作者: 水煮杰尼龟 | 来源:发表于2020-06-23 17:17 被阅读0次

   当你司产品需要一些花里胡哨的加载动画时。。。(ps:UI小姐姐给我来个gif图完事。UI小姐姐:滚,自己整)
比如下面的效果:

转圈圈.gif
有的人可能说直接撸3个layer ,让它变长变短转圈圈。
今天就来用CAReplicatorLayer 复制层来做一些这个动画。
既然用CAReplicatorLayer,顾名思义,就是可以复制,那么看上面的gif ,很明显 只用画1/3的圆就行了。
再分解一下动画,看起来是有旋转,以及变长,变短的 循环过程。
so 第一步

以左上的圆弧为本体,先在背景View上用UIBezierPath 画一个圆弧,大概角度是M_PI*5/6M_PI * 3/2,由于不是完全的1/3,所以起始角度+了M_PI/6

    self.view.backgroundColor = [UIColor blackColor];
    UIView *v = [[UIView alloc]initWithFrame:CGRectMake(100, 200, 100, 100)];
    [self.view addSubview:v];
    
    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(50, 50) radius:20 startAngle:M_PI*5/6+M_PI/6 endAngle:M_PI * 3/2 clockwise:YES];
    CAShapeLayer *layer = [CAShapeLayer layer];
    layer.path = path.CGPath;
    layer.fillColor = [UIColor clearColor].CGColor;
    layer.strokeColor = [UIColor whiteColor].CGColor;
    layer.lineWidth = 5;
    layer.lineCap = @"round";
第二步

动画已经被我分解了,流程是 圆弧变长,停留,再变短,停留。此外还加上一个整体的旋转。
所以第二步给圆弧layer增加一个圆弧变长,停留,再变短,停留的动画组。

    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    animation.fromValue = [NSNumber numberWithFloat:0];
    animation.toValue = [NSNumber numberWithFloat: 1];
    animation.duration = 0.66;
    animation.removedOnCompletion = NO;
    animation.fillMode = kCAFillModeForwards;
    
    CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"strokeStart"];
    anim.fromValue = [NSNumber numberWithFloat:0];
    anim.toValue = [NSNumber numberWithFloat: 0.95];
    anim.duration = 0.66;
    anim.beginTime = 0.66+0.2;
    anim.removedOnCompletion = NO;
    anim.fillMode = kCAFillModeForwards;
    
    CAAnimationGroup *group = [CAAnimationGroup animation];
    group.animations =@[animation,anim];
    group.fillMode = kCAFillModeForwards;
    group.duration = (0.66+0.2)*2;
    group.repeatCount = MAXFLOAT;
    [layer addAnimation:group forKey:nil];
第三步

添加CAReplicatorLayer,复制圆弧layer 。

    CAReplicatorLayer *replicatorrLayer = [CAReplicatorLayer layer];
    replicatorrLayer.frame = v.bounds;
    [v.layer addSublayer:replicatorrLayer];
    [replicatorrLayer addSublayer:layer];
    
    replicatorrLayer.instanceCount = 3; //复制 sublayer 的个数,包括创建的第一个sublayer 在内的个数
    replicatorrLayer.instanceDelay = 0; //设置动画延迟执行的时间
    replicatorrLayer.instanceAlphaOffset = 0;   //设置透明度递减
    replicatorrLayer.instanceTransform = CATransform3DMakeRotation(M_PI*2/3, 0, 0, 1);//复制条位置偏移
最后一步

给整体增加一个旋转动画,完事。

    CABasicAnimation *animation1 = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
    animation1.fromValue = [NSNumber numberWithFloat:0];
    animation1.toValue = [NSNumber numberWithFloat:M_PI*2/3];
    animation1.duration = 0.66;
    animation1.removedOnCompletion = NO;
    animation1.fillMode = kCAFillModeForwards;
    
    CABasicAnimation *animation2 = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
    animation2.fromValue = [NSNumber numberWithFloat:0];
    animation2.toValue = [NSNumber numberWithFloat:M_PI*2/3+M_PI/6];
    animation2.duration = 0.66;
    animation2.beginTime = 0.66+0.2;
    animation2.removedOnCompletion = NO;
    animation2.fillMode = kCAFillModeForwards;
    
    CAAnimationGroup *group1 = [CAAnimationGroup animation];
    group1.animations =@[animation1,animation2];
    group1.duration = (0.66+0.2)*2;
    group1.repeatCount = MAXFLOAT;
    [replicatorrLayer addAnimation:group1 forKey:nil];
以上代码最后做出来的效果如下:
转loading.gif
可以看到基本上是一毛一样的。
当然CAReplicatorLayer还能做出很多有意思的效果,自己可以去摸索摸索。
还有一些其他的效果:(代码都在文末仓库)
loading.gif
loading1.gif

完整代码

相关文章

网友评论

    本文标题:iOS 用CAReplicatorLayer做点加载动画

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