ringa_lee2017-04-18 09:46:14
提供個想法 這個應該是用三層 第一層是固定的背景就是灰色的哪一個。上面兩個白色的覆蓋層分別用strokeStart和strokeEnd實現循環的效果
#import "AnimationView.h"
@interface AnimationView ()
@property (nonatomic, strong) CAShapeLayer *path2;
@property (nonatomic, strong) CAShapeLayer *path3;
@property (nonatomic, strong) NSTimer * animationTimer;
@end
@implementation AnimationView
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self setupLayers];
self.animationTimer = [NSTimer scheduledTimerWithTimeInterval:1.113 target:self selector:@selector(loop) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop]addTimer:self.animationTimer forMode:NSDefaultRunLoopMode];
}
return self;
}
- (void)loop{
[self.path2 addAnimation:[self path2Animation] forKey:@"path2Animation"];
[self.path3 addAnimation:[self path3Animation] forKey:@"path3Animation"];
}
- (void)setupLayers{
CAShapeLayer * path = [CAShapeLayer layer];
path.frame = CGRectMake(12.67, 11.38, 19.8, 23.25);
path.lineCap = kCALineCapRound;
path.fillColor = nil;
path.strokeColor = [UIColor blackColor].CGColor;
path.lineWidth = 2;
path.path = [self pathPath].CGPath;
[self.layer addSublayer:path];
CAShapeLayer * path2 = [CAShapeLayer layer];
path2.frame = CGRectMake(12.67, 11.38, 19.8, 23.25);
path2.lineCap = kCALineCapRound;
path2.fillColor = nil;
path2.strokeColor = [UIColor whiteColor].CGColor;
path2.lineWidth = 2;
path2.path = [self path2Path].CGPath;
[self.layer addSublayer:path2];
_path2 = path2;
CAShapeLayer * path3 = [CAShapeLayer layer];
path3.frame = CGRectMake(12.67, 11.38, 19.8, 23.25);
path3.lineCap = kCALineCapSquare;
path3.fillColor = nil;
path3.strokeColor = [UIColor whiteColor].CGColor;
path3.lineWidth = 2;
path3.path = [self path3Path].CGPath;
[self.layer addSublayer:path3];
_path3 = path3;
}
- (CAAnimationGroup*)path2Animation{
CABasicAnimation * strokeStartAnim = [CABasicAnimation animationWithKeyPath:@"strokeStart"];
strokeStartAnim.fromValue = @0.9;
strokeStartAnim.toValue = @0;
strokeStartAnim.duration = 1;
strokeStartAnim.timingFunction = [CAMediaTimingFunction functionWithControlPoints:0 :0 :0 :0];
CAKeyframeAnimation * strokeEndAnim = [CAKeyframeAnimation animationWithKeyPath:@"strokeEnd"];
strokeEndAnim.values = @[@1, @0];
strokeEndAnim.keyTimes = @[@0, @1];
strokeEndAnim.duration = 1.01;
strokeEndAnim.beginTime = 0.1;
strokeEndAnim.timingFunction = [CAMediaTimingFunction functionWithControlPoints:0 :0 :0 :0];
CAAnimationGroup *pathAnimGroup = [CAAnimationGroup animation];
pathAnimGroup.animations = @[strokeStartAnim, strokeEndAnim];
[pathAnimGroup.animations setValue:kCAFillModeForwards forKeyPath:@"fillMode"];
pathAnimGroup.fillMode = kCAFillModeForwards;
pathAnimGroup.removedOnCompletion = NO;
pathAnimGroup.duration = [self maxDurationFromAnimations:pathAnimGroup.animations];
return pathAnimGroup;
}
- (CAAnimationGroup*)path3Animation{
CABasicAnimation * strokeStartAnim = [CABasicAnimation animationWithKeyPath:@"strokeStart"];
strokeStartAnim.fromValue = @1;
strokeStartAnim.toValue = @0.9;
strokeStartAnim.duration = 0.0785;
strokeStartAnim.beginTime = 1;
strokeStartAnim.timingFunction = [CAMediaTimingFunction functionWithControlPoints:0 :0 :0 :0];
CAKeyframeAnimation * hiddenAnim = [CAKeyframeAnimation animationWithKeyPath:@"hidden"];
hiddenAnim.values = @[@YES, @YES, @YES, @NO];
hiddenAnim.keyTimes = @[@0, @0.433, @0.999, @1];
hiddenAnim.duration = 1.01;
CAAnimationGroup *pathAnimGroup = [CAAnimationGroup animation];
pathAnimGroup.animations = @[strokeStartAnim, hiddenAnim];
[pathAnimGroup.animations setValue:kCAFillModeForwards forKeyPath:@"fillMode"];
pathAnimGroup.fillMode = kCAFillModeForwards;
pathAnimGroup.removedOnCompletion = NO;
pathAnimGroup.duration = [self maxDurationFromAnimations:pathAnimGroup.animations];
return pathAnimGroup;
}
#pragma mark - Bezier Path
- (UIBezierPath*)pathPath{
UIBezierPath *pathPath = [UIBezierPath bezierPath];
[pathPath moveToPoint:CGPointMake(0, 0)];
[pathPath addCurveToPoint:CGPointMake(0.408, 23.253) controlPoint1:CGPointMake(0, -0.115) controlPoint2:CGPointMake(0.408, 23.253)];
[pathPath addLineToPoint:CGPointMake(19.799, 12.881)];
[pathPath addCurveToPoint:CGPointMake(0, 0) controlPoint1:CGPointMake(19.799, 12.881) controlPoint2:CGPointMake(0, 0.116)];
return pathPath;
}
- (UIBezierPath*)path2Path{
UIBezierPath *path2Path = [UIBezierPath bezierPath];
[path2Path moveToPoint:CGPointMake(0, 0)];
[path2Path addCurveToPoint:CGPointMake(0.408, 23.253) controlPoint1:CGPointMake(0, -0.115) controlPoint2:CGPointMake(0.408, 23.253)];
[path2Path addLineToPoint:CGPointMake(19.799, 12.881)];
[path2Path addCurveToPoint:CGPointMake(0, 0) controlPoint1:CGPointMake(19.799, 12.881) controlPoint2:CGPointMake(0, 0.116)];
return path2Path;
}
- (UIBezierPath*)path3Path{
UIBezierPath *path3Path = [UIBezierPath bezierPath];
[path3Path moveToPoint:CGPointMake(0, 0)];
[path3Path addCurveToPoint:CGPointMake(0.408, 23.253) controlPoint1:CGPointMake(0, -0.115) controlPoint2:CGPointMake(0.408, 23.253)];
[path3Path addLineToPoint:CGPointMake(19.799, 12.881)];
[path3Path addCurveToPoint:CGPointMake(0, 0) controlPoint1:CGPointMake(19.799, 12.881) controlPoint2:CGPointMake(0, 0.116)];
return path3Path;
}
- (CGFloat)maxDurationFromAnimations:(NSArray*)anims{
CGFloat maxDuration = 0;
for (CAAnimation *anim in anims) {
maxDuration = MAX(anim.beginTime + anim.duration * (CGFloat)(anim.repeatCount == 0 ? 1.0f : anim.repeatCount) * (anim.autoreverses ? 2.0f : 1.0f), maxDuration);
}
if (maxDuration == INFINITY) {
maxDuration = 1000.0f;
}
return maxDuration;
}
-(void)dealloc {
//自己取消 定时器
}