I am creating an app that involves animating lines within a workspace over time. My current approach for this is to use code like this in drawRect
:
CGContextSetStrokeColor(context, black);
CGContextBeginPath(context);
CGContextMoveToPoint(context, startPoint.x, startPoint.y);
CGContextAddLineToPoint(context, finalPoint.x, finalPoint.y);
CGContextStrokePath(context);
...and then just setting a timer to run every 0.05 seconds to update finalPoint
and call setNeedsDisplay
.
I'm finding this approach (when there's 5ish lines moving at once) slows down the app terribly, and even with such a high refresh frequency, still appears jerky.
There must be some better way to perform this very simple line drawing in an animated line - i.e. saying that I want a line to start at x1, y1 and stretching to x2, y2 over a given length of time. What are my options for this? I need to make this perform faster and would love to get rid of this clunky timer.
Thanks!
Use CAShapeLayers, and a combination of CATransactions and CABasicAnimation.
You can add a given path to a shapeLayer and let it do the rendering.
A CAShapeLayer object has two properties called
strokeStart
andstrokeEnd
, which defines where along the path the end of the line should render. The defaults are 0.0 forstrokeStart
, and 1.0 forstrokeEnd
.If you set up your path so that
strokeEnd
initially starts at 0.0, you will see no line.You can then animate, from 0.0 to 1.0, the
strokeEnd
property and you will see the line lengthen.To change CAShapeLayer's implicit 0.25s default animation timing, you can add a function to the class, like so:
You can pass any value from 0.0f to 1.0f as the value of
_strokeEnd
.The
setCompletionBlock:
ensures that the value you are passing is explicitly set after the animation completes.