Rajesh Maurya
Rajesh Maurya

Reputation: 3164

CAKeyFrameAnimation with different time duration on a particular UIBezierPath?

I want to animate a image onto a UIBezierPath with duration of 12 seconds. I am using CAKeyframeAnimation for that. My problem is that i want to animate image for 2 sec from starting point to firstPoint, for 4 sec from first point to second point, for 4 sec from second point to third point and for 2 sec from third point to end point. How can i do this? Here is my code.

CGPoint startingpoint = CGPointMake(self.bounds.origin.x + 98, self.bounds.size.height -20);
CGPoint firstPoint = CGPointMake(startingpoint.x + 20,startingpoint.y);
CGPoint secondpoint = CGPointMake(firstPoint.x + 30,firstPoint.y - 80);
CGPoint thirdpoint = CGPointMake(secondpoint.x + 50, secondpoint.y + 80);
CGPoint endPoints = CGPointMake(thirdpoint.x + 20,thirdpoint.y);

UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:startingpoint];
[path addLineToPoint:firstPoint];
[path addLineToPoint:secondpoint];
[path addLineToPoint:thirdpoint];
[path addLineToPoint:endPoints];

CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.path = [path CGPath];
shapeLayer.strokeColor = [[UIColor whiteColor] CGColor];
shapeLayer.lineWidth = 3.0;
shapeLayer.fillColor = [[UIColor clearColor] CGColor];
[self.layer addSublayer:shapeLayer];

CAKeyframeAnimation *animation1 = [CAKeyframeAnimation animationWithKeyPath:@"position"];
animation1.duration = 10;
animation1.path = path.CGPath;
animation1.autoreverses = NO;
animation1.repeatCount = 0;
[myImageView.layer addAnimation:animation1 forKey:@"position"];

Upvotes: 0

Views: 678

Answers (1)

Aaron
Aaron

Reputation: 7145

You're missing a few things on your animation. Specifically you're not setting any keyTimes or values on your CAKeyframeAnimation. Even though they're optional, Core Animation doesn't know that you want a value changed at 2 seconds and then again 4 seconds later. You have to tell the animation what you want.

To do that you need two NSArrays of equal length. The first will have the times for your key frames as a factor of your animation's total time:

CFTimeInterval d = 12.0f; // 12 seconds total time
NSArray * keyTimes = @[@(0), @(2/d), @(6/d), @(10/d), @(1.0)];

And the other will be a list of values (in this case CGPoint wrapped in NSValues because you're animating a CGPoint typed property) to which those keyTimes will correspond:

NSArray * pointValues = @[[NSValue valueWithCGPoint:startingPoint], [NSValue valueWithCGPoint:firstPoint], [NSValue valueWithCGPoint:secondPoint], [NSValue valueWithCGPoint:thirdPoint], [NSValue valueWithCGPoint:endPoint]];

Finally set them on the animation:

animation1.keyTimes = keyTimes;
animation1.values = values;

If you want to get really fancy you can also specify an n-1 length array of timing functions for the timing of each value change between the provided key times:

CAMediaTimingFunction * linear = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
CAMediaTimingFunction * easeIn = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
CAMediaTimingFunction * fastEaseInOut = [CAMediaTimingFunction functionWithControlPoints:0.30f :0.92f :0.86f :0.95f];

NSArray * timingFunctions = @[easeIn, linear, linear, fastEaseInOut];
animation1.timingFunctions = timingFunctions;

Upvotes: 1

Related Questions