动画绘制线条

我试图通过以下方式为线条绘制动画:

。H

CAShapeLayer *rootLayer; CAShapeLayer *lineLayer; CGMutablePathRef path; 

.M

  path = CGPathCreateMutable(); CGPathMoveToPoint(path, nil, self.frame.size.width/2-100, 260); CGPathAddLineToPoint(path, nil, self.frame.size.width/2+100.0, 260); CGPathCloseSubpath(path); self.rootLayer = [CALayer layer]; rootLayer.frame = self.bounds; [self.layer addSublayer:rootLayer]; self.lineLayer = [CAShapeLayer layer]; [lineLayer setPath:path]; [lineLayer setFillColor:[UIColor redColor].CGColor]; [lineLayer setStrokeColor:[UIColor blueColor].CGColor]; [lineLayer setLineWidth:1.5]; [lineLayer setFillRule:kCAFillRuleNonZero]; [rootLayer addSublayer:lineLayer]; [self performSelector:@selector(startTotalLine) withObject:nil afterDelay:1.5]; - (void)startTotalLine { CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"animatePath"]; [animation setDuration:3.5]; animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; [animation setAutoreverses:NO]; [animation setFromValue:(id)path]; [animation setToValue:(id)path]; [lineLayer addAnimation:animation forKey:@"animatePath"]; } 

在调用startTotalLine方法之前绘制了该行。 此外, startTotalLine方法不会影响该行。

我想让它从右到左为线条画设置动画。

我认为最简单的方法就是提供一些1.5像素高度的UIView并为其宽度设置动画。 问我是否不清楚。

我认为您的代码不起作用,因为您的变量path不是图层属性。 阅读手册 :

CABasicAnimation为图层属性提供基本的单关键帧动画function。

你在这做一些奇怪的事:

 [animation setFromValue:(id)path]; [animation setToValue:(id)path]; 

编辑:我偶然发现了一篇文章 ,并了解了你想要实现的目标! 现在我认为你失败的原因是你可以设置不改变点数的路径动画。 而现在我认为你可以创建一个有两个点的路径。 起初他们在同一个地方,另一条路是你想要最终的路线。 现在从第一条路径动画到第二条路径。 我认为它应该有效,但我不确定。

编辑:绝对! 你需要这个人的代码。 Git链接 。

我会用动画属性来做。

为了实现这一点,我将创建一个自定义CALayer类 – 让我们称之为LineLayer 。 定义startPoint属性和length属性。 然后我将length属性配置为“animatable”。

该代码看起来如下所示:

 // LineLayer.h @interface LineLayer: CALayer @property (nonatomic, assign) int length; // This was omitted from the SO code snippet. @property (nonatomic, assign) CGPoint startPoint; @end // LineLayer.m @implementation LineLayer @synthesize length = _length; // This was omitted from the SO code snippet. @synthesize startPoint= _startPoint; - (id) initWithLayer:(id)layer { if(self = [super initWithLayer:layer]) { if([layer isKindOfClass:[LineLayer class]]) { // This bit is required for when we CA is interpolating the values. LineLayer *other = (LineLayer*)layer; self.length = other.length; self.startPoint = other.startPoint; // This was omitted. } } return self; } + (BOOL)needsDisplayForKey:(NSString *)key { if ([key isEqualToString:@"length"]) { return YES; } return [super needsDisplayForKey:key]; } - (void) setLength:(int)newLength { if (newLength < 0) { return; // Fail early. } _length = newLength; [self setNeedsDisplay]; } /* This should have been drawInContext:(CGContextRef)context - (void) drawRect:(CGRect) rect */ - (void) drawInContext:(CGContextRef)context { //...Do your regular drawing here. // This was omitted from the SO code snippet. CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor); CGContextSetLineWidth(context, 2); CGContextMoveToPoint(context, _startPoint.x, _startPoint.y); CGContextAddLineToPoint(context, _startPoint.x + _length, _startPoint.y); CGContextStrokePath(context); } @end 

然后在您的视图控制器中,您可以像这样使用LineLayer

 - (void)viewDidLoad { [super viewDidLoad]; LineLayer *lineLayer = [LineLayer new]; // This was omitted from the SO code snippet. lineLayer.frame = CGRectMake(0, 0, 320, 480); [lineLayer setNeedsDisplay]; // --- lineLayer.startPoint = CGPointMake(0, 100); lineLayer.length = 0; [self.view.layer addSublayer:lineLayer]; // Now animate the changes to the length property CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"length"]; anim.duration = 5; // Change should table about 5 mins. anim.fromValue = [NSNumber numberWithInt:0]; anim.toValue = [NSNumber numberWithInt:200]; [lineLayer addAnimation:anim forKey:@"animateLength"]; lineLayer.length = 200; //Do clean up below... } 

快乐编码:)

以下是我的解决方案,使用“UIBezierPath”,“CAShapeLayer”和属性“strokeEnd”:

.m文件

 @synthesize shapeLayer; [self drawLine]; -(void)drawLine { CGFloat X1 = self.frame.size.width/2-100; CGFloat Y1 = 260; CGFloat X2 = self.frame.size.width/2+100.0; CGFloat Y2 = 260; UIBezierPath *path = [UIBezierPath bezierPath]; [path moveToPoint:CGPointMake(X1, Y1)]; [path addLineToPoint:CGPointMake(X2, Y2)]; CAShapeLayer *shapeLayer = [CAShapeLayer layer]; shapeLayer.path = [path CGPath]; shapeLayer.strokeColor = [[UIColor blueColor] CGColor]; shapeLayer.lineWidth = 1.5; shapeLayer.fillColor = [[UIColor redColor] CGColor]; shapeLayer.strokeEnd =0; [self.layer addSublayer:shapeLayer]; [self performSelector:@selector(startTotalLine) withObject:nil afterDelay:1.5]; } - (void)startTotalLine { CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; animation.duration = 3.5f; animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; [animation setAutoreverses:NO]; [animation setFromValue:[NSNumber numberWithInt:0]]; [animation setToValue:[NSNumber numberWithInt:1]]; [shapeLayer addAnimation:animation forKey:@"animatePath"]; } 

默认的“strokeEnd”值为1,因此,在开头将其设为0(不显示任何行)。 顺便说一下,这里有一些有用的例子: http : //jamesonquave.com/blog/fun-with-cashapelayer/