84669 personnes étudient
152542 personnes étudient
20005 personnes étudient
5487 personnes étudient
7821 personnes étudient
359900 personnes étudient
3350 personnes étudient
180660 personnes étudient
48569 personnes étudient
18603 personnes étudient
40936 personnes étudient
1549 personnes étudient
1183 personnes étudient
32909 personnes étudient
如图,用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