Search code examples
iosanimationsprite-kitcore-animation

How to animate a line over duration?


I am new programmer developing an iOS game and would like to program an animated line to guide the user to drag an object from point A to point B. So I'd like the line to start (with length = 0) at point A and animate itself (to say length = 100 pixels) to point B.

I am using SKShapeNode, and currently to 'animate' it, I am really recreating the line each frame through the "update" method with a variable that depends on currentTime for the line to be slightly longer and longer length until it reaches the desired length using the following code (note that the line is dashed):

However I'm running into several performance issues that when I fix, cascade into more. I need to step away from having the object's length a function of the time that has elapsed from "-(void)update:(CFTimeInterval)currentTime". Instead I want to have one method that can be called to animate this line - I was reading and feel like this might be achievable through CoreAnimations (like CABasicAnimation here Ios drawing lines animated) but I'm not sure exactly how to accomplish this. Any help or guidance in the right direction would be much appreciated - thanks. Let me know if I can provide any additional information or explanation on anything!

-(void)drawLine : (CGFloat)ratio 
{


    CGPoint StartPoint = CGPointMake(0,0)
    CGPoint FinishPoint = CGPointMake(100,50);
    CGPoint AnimatedPoint = CGPointMake(FinishPoint.x*ratio +StartPoint.x*(1-ratio)+1, FinishPoint.y*ratio+StartPoint.y*(1-ratio)+1);

    CGFloat pattern[2];
    pattern[0] = self.size.height/30; //length of first pattern
    pattern[1] = self.size.height/30; //length of second pattern

    UIBezierPath *bezierPath=[UIBezierPath bezierPath];
    [bezierPath moveToPoint:StartPoint];
    [bezierPath addLineToPoint:AnimatedPoint];

    CGPathRef dashed =
    CGPathCreateCopyByDashingPath([bezierPath CGPath],
                                  NULL,
                                  0,
                                  pattern,
                                  2);
    lineDrawn.path = dashed; //this is of type SKShapeNode
    CGPathRelease(dashed);
}

Solution

  • Yes, you can (and probably should) use Core Animation instead of trying to draw your lines in a loop.

    What you would do would be to create a CAShapeLayer. You'd install the CGPath from your UIBezierPath as the path in your shape layer, and add the shape layer as a sublayer of some view's layer in your view hierarchy.

    You'd then create a CABasicAnimation that would animate the strokeEnd property of the shape layer from 0 (end = beginning: no line drawn) to 1.0 (line drawn fully from beginning to end.

    This is a pretty common technique. You should be able to do a google search on "CAShapeLayer CABasicAnimation strokeEnd" and find examples that do more or less what you need to do. If You can't find any let me know and I'll point you in the right direction.