I approaching core animation and drawing empirically. I am trying to animate a simple shape; the shape in question is formed by 3 lines plus a bezier curve. A red line is also drawn, to show the curve control points.
alt text http://img.skitch.com/20091119-1ufar435jdq7nwh8pid5cb6kmm.jpg
My main controller simply adds this subview and calls the adjustWave
method whenever touchesEnd
.
Here is the code for my shape drawing class. As you see the class has one property, cp1x (the x of the bezier control point 1). This is the value I would like to animate. Mind, this is a dumb attempt ...
- (void)drawRect:(CGRect)rect {
float cp1y = 230.0f;
float cp2x = 100.0f;
float cp2y = 120.0f;
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextClearRect(ctx, rect);
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, 10.0f, 200.0f);
CGPathAddCurveToPoint (path, NULL, cp1x, cp1y, cp2x, cp2y, 300.0f, 200.0f);
CGPathAddLineToPoint(path, NULL, 300.0f, 300.0f);
CGPathAddLineToPoint(path, NULL, 10.0f, 300.0f);
CGPathCloseSubpath(path);
CGContextSetFillColorWithColor(ctx, [UIColor blueColor].CGColor);
CGContextAddPath(ctx, path);
CGContextFillPath(ctx);
// Drawing a line from control points 1 and 2
CGContextBeginPath(ctx);
CGContextSetRGBStrokeColor(ctx,1,0,0,1);
CGMutablePathRef cp1 = CGPathCreateMutable();
CGPathMoveToPoint(cp1, NULL, cp1x, cp1y);
CGPathAddLineToPoint(cp1, NULL, cp2x, cp2y);
CGPathCloseSubpath(cp1);
CGContextAddPath(ctx, cp1);
CGContextStrokePath(ctx);
}
- (void)adjustWave {
[UIView beginAnimations:@"movement" context:nil];
[UIView setAnimationDelegate:self];
[UIView setAnimationWillStartSelector:@selector(didStart:context:)];
[UIView setAnimationDidStopSelector:@selector(didStop:finished:context:)];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
[UIView setAnimationDuration:3.0f];
[UIView setAnimationRepeatCount:3];
[UIView setAnimationRepeatAutoreverses:YES];
cp1x = cp1x + 20.0f;
[UIView commitAnimations];
}
The shape doesn't change. If, conversely, I take out the CA code and add a simple `[self setNeedsDisplay] in the last method the shape changes, but obviously without CA. Can you help sme? I am sure I am making a very basic mistake here… Thanks in advance, Davide
Layer animations work much like view animations; you simply animate a property between a start and an end value over a defined period of time and let Core Animation take care of the rendering in between.
Overview. Core Animation provides high frame rates and smooth animations without burdening the CPU and slowing down your app. Most of the work required to draw each frame of an animation is done for you.
Just about every object you can create in Sketchpad can be animated. To animate an object, you can choose Display | Animate, use the Motion Controller, or create an Animation action button.
If you are writing this for iPhone OS 3.x (or Snow Leopard), the new CAShapeLayer class should let you do this kind of animation pretty easily. If you have a path that maintains the same number of control points (like in your case), you can set that path to the CAShapeLayer, then animate the path property from that starting value to your final path. Core Animation will perform the appropriate interpolation of the control points in the path to animate it between those two states (more, if you use a CAKeyframeAnimation).
Note that this is a layer, so you will need to add it as a sublayer of your UIView. Also, I don't believe that the path property implicitly animates, so you may need to manually create a CABasicAnimation to animate the change in shape from path 1 to path 2.
EDIT (11/21/2009): Joe Ricioppo has a nice writeup about CAShapeLayer here, including some videos that show off these kinds of animations.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With