我正在创建一个应用程序,该应用程序涉及随着时间的推移动画工作区内的线条。我目前的做法是在drawRect
:
CGContextSetStrokeColor(context, black);
CGContextBeginPath(context);
CGContextMoveToPoint(context, startPoint.x, startPoint.y);
CGContextAddLineToPoint(context, finalPoint.x, finalPoint.y);
CGContextStrokePath(context);
...然后只需将计时器设置为每0.05秒运行一次,以更新finalPoint
并致电setNeedsDisplay
。
我发现这种方法(当有5条线路同时移动时)会严重减慢应用程序速度,即使刷新频率如此之高,仍然会显得生涩。
必须有一些更好的方法在动画线中执行这个非常简单的线条绘制 - 即说我想要一条线从x1,y1开始并在给定的时间长度内拉伸到x2,y2。我有什么选择?我需要让这个表演更快,并且希望摆脱这个笨重的计时器。
谢谢!
答案 0 :(得分:5)
使用CAShapeLayers,以及CATransactions和CABasicAnimation的组合。
您可以将给定路径添加到shapeLayer并让它进行渲染。
CAShapeLayer对象有两个名为strokeStart
和strokeEnd
的属性,它定义了行的末尾应该呈现的路径。 strokeStart
的默认值为0.0,strokeEnd
的默认值为1.0。
如果您设置路径以使strokeEnd
最初从0.0开始,您将看不到任何行。
然后,您可以将strokeEnd
属性设置为0.0到1.0的动画,您将看到该行延长。
要更改CAShapeLayer的隐式0.25s默认动画时序,您可以向该类添加一个函数,如下所示:
-(void)animateStrokeEnd:(CGFloat)_strokeEnd {
[CATransaction begin];
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:keyPath];
animation.duration = 2.0f; //or however long you want it to happen
animation.fromValue = [NSNumber numberWithFloat:self.strokeEnd]; // from the current strokeEnd value
animation.toValue = [NSNumber numberWithFloat:_strokeEnd]; //to the end of the path
[CATransaction setCompletionBlock:^{ self.strokeEnd = _strokeEnd }];
[self addAnimation:animation forKey:@"animateStrokeEnd"];
[CATransaction commit];
}
您可以将任何值从0.0f传递到1.0f作为_strokeEnd
的值。
setCompletionBlock:
确保在动画完成后显式设置您传递的值。