iOS Development by David Casserly

From the Blog

Mar
03

iPhone: Animate an object along a path

Posted by admin on March 3rd, 2010 at 9:39 pm

Here i will show you how to animate an object along a path on a UIView. I will create the path and draw it onto the UIView so that you can see it, and then use the same path for the animation.

I’m doing all of this within a UIView that i have added to my screen…

Animate along a path

Firstly, we will draw a curved line on the screen….

//This draws a quadratic bezier curved line right across the screen
- ( void ) drawACurvedLine {
	//Create a bitmap graphics context, you will later get a UIImage from this
	UIGraphicsBeginImageContext(CGSizeMake(320,460));
	CGContextRef ctx = UIGraphicsGetCurrentContext();
	
	//Set variables in the context for drawing
	CGContextSetLineWidth(ctx, 1.5);
	CGContextSetStrokeColorWithColor(ctx, [UIColor whiteColor].CGColor);
	
	//Set the start point of your drawing
	CGContextMoveToPoint(ctx, 10, 10);
	//The end point of the line is 310,450 .... i'm also setting a reference point of 10,450
	//A quadratic bezier curve is drawn using these coordinates - experiment and see the results.
	CGContextAddQuadCurveToPoint(ctx, 10, 450, 310, 450);
	//Add another curve, the opposite of the above - finishing back where we started
	CGContextAddQuadCurveToPoint(ctx, 310, 10, 10, 10);
	
	//Draw the line 
	CGContextDrawPath(ctx, kCGPathStroke);
	
	//Get a UIImage from the current bitmap context we created at the start and then end the image context
	UIImage *curve = UIGraphicsGetImageFromCurrentImageContext();
	UIGraphicsEndImageContext();
	
	//With the image, we need a UIImageView
	UIImageView *curveView = [[UIImageView alloc] initWithImage:curve];
	//Set the frame of the view - which is used to position it when we add it to our current UIView
	curveView.frame = CGRectMake(1, 1, 320, 460);
	curveView.backgroundColor = [UIColor clearColor];
	[self addSubview:curveView];
}

Now we will create a keyframe animation, and a path that is the same as the line we just drew. We will also draw a circle, and animate it along that path:

- (void) animateCicleAlongPath {
	//Prepare the animation - we use keyframe animation for animations of this complexity
	CAKeyframeAnimation *pathAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
	//Set some variables on the animation
	pathAnimation.calculationMode = kCAAnimationPaced;
	//We want the animation to persist - not so important in this case - but kept for clarity
	//If we animated something from left to right - and we wanted it to stay in the new position, 
	//then we would need these parameters
	pathAnimation.fillMode = kCAFillModeForwards;
	pathAnimation.removedOnCompletion = NO;
	pathAnimation.duration = 5.0;
	//Lets loop continuously for the demonstration
	pathAnimation.repeatCount = 1000;
	
	//Setup the path for the animation - this is very similar as the code the draw the line
	//instead of drawing to the graphics context, instead we draw lines on a CGPathRef
	CGPoint endPoint = CGPointMake(310, 450);
	CGMutablePathRef curvedPath = CGPathCreateMutable();
	CGPathMoveToPoint(curvedPath, NULL, 10, 10);
	CGPathAddQuadCurveToPoint(curvedPath, NULL, 10, 450, 310, 450);
	CGPathAddQuadCurveToPoint(curvedPath, NULL, 310, 10, 10, 10);
	
	//Now we have the path, we tell the animation we want to use this path - then we release the path
	pathAnimation.path = curvedPath;
	CGPathRelease(curvedPath);
	
	//We will now draw a circle at the start of the path which we will animate to follow the path
	//We use the same technique as before to draw to a bitmap context and then eventually create
	//a UIImageView which we add to our view
	UIGraphicsBeginImageContext(CGSizeMake(20,20));
	CGContextRef ctx = UIGraphicsGetCurrentContext();	
	//Set context variables
	CGContextSetLineWidth(ctx, 1.5);
	CGContextSetFillColorWithColor(ctx, [UIColor greenColor].CGColor);
	CGContextSetStrokeColorWithColor(ctx, [UIColor whiteColor].CGColor);
	//Draw a circle - and paint it with a different outline (white) and fill color (green)
	CGContextAddEllipseInRect(ctx, CGRectMake(1, 1, 18, 18));
	CGContextDrawPath(ctx, kCGPathFillStroke);
	UIImage *circle = UIGraphicsGetImageFromCurrentImageContext();
	UIGraphicsEndImageContext();
	
	UIImageView *circleView = [[UIImageView alloc] initWithImage:circle];
	circleView.frame = CGRectMake(1, 1, 20, 20);
	[self addSubview:circleView];

	//Add the animation to the circleView - once you add the animation to the layer, the animation starts
	[circleView.layer addAnimation:pathAnimation forKey:@"moveTheSquare"];	
}

To get all this running, you can use this init method:

- (id)initWithFrame:(CGRect)frame {
	if (self = [super initWithFrame:frame]) {
		[self drawACurvedLine];
		[self animateCicleAlongPath];		
    }
    return self;
}

and use something like this in your ViewController….

- (void)viewDidLoad {
	UIView *customView = [[Canvas alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
	customView.backgroundColor = [UIColor blackColor];
	[self.view addSubview:customView];
	[customView release];
    [super viewDidLoad];
}

Also…don’t forget to add your Quartz import:

#import <QuartzCore/QuartzCore.h>

I’m sure there are lots of better ways of doing this, such as using CALayers and adding CGImage to the layers. But that’s something I haven’t tried yet. The example above should be enough to get you started with animation along a path.

Here is a copy of the XCode project:
xcodeProject

Leave a Reply

7 Responses to iPhone: Animate an object along a path

  1.  

    |

  2. Hi, for long time i looking for Animate an object along a path tutorial.
    i make a small project with such animation and i couldn’t make it right and i get stuck with this tutorial :( . can you please send to my email the full project of this tutorial? :D

    TNX
    Diabolo

  3. Mital Pritmani |

    hello,

    this was a great tutorial and really really thank you for the project code also.

    The code was really very helpful and i got the animation full code from ur tutorial only so thank yo so much again.

  4. Excellent weblog right here! Also your web site lots up very fast! What host are you using? Can I get your associate link to your host? I desire my website loaded up as quickly as yours lol