贝塞尔曲线进度条转圈小动画
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