Magic Bullet Dave
Magic Bullet Dave

Reputation: 9076

CALayer setPosition not called during animation

I have a custom CALayer that I am animating using a CAAnimationGroup to follow a path and rotate at a tangent to the path:

   // Create the animation path
CAKeyframeAnimation *pathAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
pathAnimation.calculationMode = kCAAnimationPaced;
pathAnimation.fillMode = kCAFillModeForwards;
pathAnimation.removedOnCompletion = NO;

//Setting Endpoint of the animation
CGRect contentBounds = [self contentBounds];
self.boatLayer.bounds = contentBounds;
CGPoint endPoint = CGPointMake(contentBounds.size.width - 150, contentBounds.size.height - 150);

CGMutablePathRef curvedPath = CGPathCreateMutable();
CGPathMoveToPoint(curvedPath, NULL, startPosition.x, startPosition.y);
CGPathAddCurveToPoint(curvedPath, NULL, endPoint.x, 0, endPoint.x, 0, endPoint.x, endPoint.y);
pathAnimation.path = curvedPath;

pathAnimation.duration = 10.0;
pathAnimation.rotationMode = kCAAnimationRotateAuto;
pathAnimation.delegate = self;

// Create an animation group of all the animations
CAAnimationGroup *animationGroup = [[[CAAnimationGroup alloc] init] autorelease];
animationGroup.animations = [NSArray arrayWithObjects:pathAnimation, nil];
animationGroup.duration = 10.0;
animationGroup.removedOnCompletion = NO;

// Add the animations group to the layer (this starts the animation at the next refresh cycle)
[testLayer addAnimation:animationGroup forKey:@"animation"];

I need to be able to track the changes to the position and rotation of the layer as it progresses along the path. I have overridden both setPosition and setTransform (calling super setPosition and super setTranform) and then logging their values. Neither of these values appear to be set during the animation.

How can I get the position and rotation updates from within the CALayer class itself as it animates?

Upvotes: 0

Views: 287

Answers (1)

David Rönnqvist
David Rönnqvist

Reputation: 56645

Core Animation doesn't work like that

Sorry. That is not how Core Animation work. When you add an animation to a layer it doesn't change the model of that layer. Only the presentation.

When you configure then animation to not remove itself upon completion

yourAnimation.fillMode = kCAFillModeForwards;
tourAnimation.removedOnCompletion = NO;

you are actually causing an inconsistency between what is shown on screen and the model of that layer. If you for instance had a button that you animated like this you would get very surprised/angry by the fact that it "no longer responds to toucher" or even more funny "responds to touches from it's 'old' location".

Semi-solutions

Depending on what and how often you actually need the updates you could either periodically check the value of the presentationLayer during the animation or use a CADisplayLink to run some code when the screen changes.

Upvotes: 1

Related Questions