巧用CAShapeLayer自定义loading

2017-11-27  本文已影响7人  码尼格特

这里要提到的是app中开发 经常自定义的loading状态 无论是头部刷新 页面加载 所用到的部分

一般的思路是用UIBezierPath路径绘制CAShapeLayer 用strokeColor,fillColor,lineWidth等构建基本形状,虚线用lineDashPattern,圆头形状用lineCap

这里要提到的就是CA动画的2个keypath,一个是strokeStart,一个是strokeEnd,start默认是0,
end默认是1,顾名思义,可以理解为路径的起始处和终结处的百分比,利用这个属性,我们可以利用时间差去构造各种复杂的填充动画

构造layer

    CAShapeLayer *backShapeLayer = [CAShapeLayer layer];
    backShapeLayer.strokeColor = [UIColor colorWithRed:229/255.0 green:229/255.0 blue:229/255.0 alpha:1].CGColor;
    backShapeLayer.fillColor = [UIColor clearColor].CGColor;
    backShapeLayer.lineWidth = 2.f;
    backShapeLayer.path = [UIBezierPath
                             bezierPathWithRoundedRect:CGRectMake((self.view.frame.size.width - 100)/2, (self.view.frame.size.height - 100)/2, 100, 100) cornerRadius:50].CGPath;
    [self.view.layer addSublayer:backShapeLayer];
    // 外部虚线layer
    CAShapeLayer *innerLayer1 = [CAShapeLayer layer];
    innerLayer1.strokeColor = [UIColor redColor].CGColor;
    innerLayer1.fillColor = [UIColor clearColor].CGColor;
    innerLayer1.lineWidth = KShapelayerLineWidth;
    innerLayer1.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake((self.view.frame.size.width - 100)/2, (self.view.frame.size.height - 100)/2,100, 100) cornerRadius:50].CGPath;
    innerLayer1.lineDashPattern = @[@10,@5];
    [self.view.layer addSublayer:innerLayer1];
    [self animationWithTargetLayer:innerLayer1 clockwise:YES];
    
    //内部圆角layer
    CAShapeLayer *innerLayer2 = [CAShapeLayer layer];
    innerLayer2.strokeColor = [UIColor blueColor].CGColor;
    innerLayer2.fillColor = [UIColor clearColor].CGColor;
    innerLayer2.lineWidth = KShapelayerLineWidth;
    innerLayer2.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake((self.view.frame.size.width - 60)/2, (self.view.frame.size.height - 60)/2,60, 60) cornerRadius:50].CGPath;
    innerLayer2.lineCap = kCALineCapRound;
    [self.view.layer addSublayer:innerLayer2];
    [self animationWithTargetLayer:innerLayer2 clockwise:NO];

利用animationGroup构造动画 利用时间差完成效果

- (void)animationWithTargetLayer:(CALayer *)layer clockwise:(BOOL)clockwise
{
    // 起点动画
    CABasicAnimation * strokeStartAnimation = [CABasicAnimation animationWithKeyPath:@"strokeStart"];
    strokeStartAnimation.fromValue = clockwise ? @(-1) : @(1);
    strokeStartAnimation.toValue = clockwise ? @(1) : @(-1);
    
    // 终点动画
    CABasicAnimation * strokeEndAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    strokeEndAnimation.fromValue = clockwise ? @(0) : @(1);
    strokeEndAnimation.toValue = clockwise ? @(1) : @(0);
    
    // 组合动画
    CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
    animationGroup.animations = @[strokeStartAnimation];
    animationGroup.duration = 2;
    animationGroup.repeatCount = CGFLOAT_MAX;
    animationGroup.fillMode = kCAFillModeForwards;
    animationGroup.removedOnCompletion = NO;
    [layer addAnimation:animationGroup forKey:nil];
}

完成效果

animation.gif
上一篇 下一篇

猜你喜欢

热点阅读