如图,用strokeStart和strokeEnd实现不了,不知道怎么做了
走同样的路,发现不同的人生
Donnez-moi une idée. Cela devrait utiliser trois calques. Le premier calque est un arrière-plan fixe, qui est gris. Les deux superpositions blanches ci-dessus utilisent respectivement StrokeStart et StrokeEnd pour obtenir l'effet de boucle
#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 { //自己取消 定时器 }
Donnez-moi une idée. Cela devrait utiliser trois calques. Le premier calque est un arrière-plan fixe, qui est gris. Les deux superpositions blanches ci-dessus utilisent respectivement StrokeStart et StrokeEnd pour obtenir l'effet de boucle