贝塞尔曲线进度条转圈小动画

2020-07-14  本文已影响0人  哥只是个菜鸟
#import "Circleview.h"

@interface Circleview ()<CAAnimationDelegate>
{
    CAShapeLayer *_shaperLayer;
    CFTimeInterval _druration;
}

@end
@implementation Circleview

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        [self configBgCircle];
        _druration=1.5;
    }
    return self;
}

- (void)configBgCircle {
    UIBezierPath *bPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.frame.size.width * 0.5, self.frame.size.height * 0.5) radius:95.f/2 startAngle:(1.3*M_PI) endAngle:(2.2*M_PI) clockwise:YES];
    _shaperLayer = [CAShapeLayer layer];
    _shaperLayer.fillColor = [UIColor clearColor].CGColor;
    _shaperLayer.strokeColor = [UIColor blueColor].CGColor;
    _shaperLayer.lineWidth = 4;
    _shaperLayer.path = bPath.CGPath;
    [self.layer addSublayer:_shaperLayer];
    
    // 动画调整轨道的结束点 ---
    // 设置需要执行动画的属性path
    CABasicAnimation *strokeEndAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    // 设置动画的其实点和结束点
    strokeEndAnimation.fromValue = @0.0;
    strokeEndAnimation.toValue = @1;
    // 设置动画时间
    strokeEndAnimation.duration = 0.4;
    // 设置动画函数类型
    strokeEndAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    
    // 动画调整轨道的开始点 相当于清除轨迹,
    CABasicAnimation *strokeStartAnimation = [CABasicAnimation animationWithKeyPath:@"strokeStart"];
    strokeStartAnimation.fromValue = @0.0;
    strokeStartAnimation.toValue = @1;
    // 时间比绘制时少, 看上去清除比较快
    strokeStartAnimation.duration = 0.4;
    // 设置动画开始时间 在上面的动画执行完毕后在执行 --- 看上去就像是在清除轨道
    strokeStartAnimation.beginTime = 1.0;
    strokeStartAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    
    //    CABasicAnimation *colorAnimation = [CABasicAnimation animationWithKeyPath:@"strokeColor"];
    //    colorAnimation.toValue = (id)[[UIColor blueColor] CGColor];
    //    colorAnimation.duration = duration;
    
    CAAnimationGroup *groupAnimation = [CAAnimationGroup animation];
    // 设置包含的动画, 先后顺序由设置的beginTime决定
    groupAnimation.animations = @[strokeEndAnimation, strokeStartAnimation];
    groupAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    groupAnimation.fillMode = kCAFillModeForwards;
    // 组动画执行时间 == 上面两个动画时间之和
    groupAnimation.duration = 1.4;
    // 重复次数 设置为无限大
    groupAnimation.repeatCount = 1;
    // 设置模式
    groupAnimation.fillMode = kCAFillModeForwards;
    
    // 在使用旋转动画来旋转self.layer 使每次重合的位置动态变化
    CABasicAnimation *rotation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
    rotation.delegate=self;
    rotation.fromValue = @0.0;
    rotation.toValue = @(1.4 * M_PI);
    rotation.duration = 1.4;
    rotation.repeatCount = 1;
    [_shaperLayer addAnimation:groupAnimation forKey:@"group"];
    [self.layer addAnimation:rotation forKey:@"roration"];
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        UIBezierPath *Path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.frame.size.width * 0.5, self.frame.size.height * 0.5) radius:95.f/2 startAngle:(0*M_PI) endAngle:(0*M_PI) clockwise:YES];
        _shaperLayer.path = Path.CGPath;
    });
}

//动画开始时
- (void)animationDidStart:(CAAnimation *)anim
{
    NSLog(@"开始了");
}

//动画结束时
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
    [_shaperLayer removeAllAnimations]; //方法中的flag参数表明了动画是自然结束还是被打断,比如调用了removeAnimationForKey:方法或removeAnimationForKey方法,flag为NO,如果是正常结束,flag为YES。
    NSLog(@"结束了");
    [_shaperLayer removeFromSuperlayer];
    
}
@end
上一篇 下一篇

猜你喜欢

热点阅读