Dermot
Dermot

Reputation: 1743

Set initial AffineTransform on layer, then animate cumulative transform?

I've put together a clock animation using QuartzCore on iOS. Each clock hand is a UIView Currently, I position the second hand at 12 O Clock & set the anchor point of the second hand view to 0.5, 1.0 so it rotates around its bottom (rather than centre point). Then I add the following animation to the layer:

(note, this uses a category on CAKeyFrameAnimation to enable a custom easing function, but its outside the scope of the question. For all intents & purposes, the animation behaves just like a regular CABasicAnimation)

CAKeyframeAnimation *secondHandRotation;
secondHandRotation = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"
                                                      function:BounceEaseOut
                                                     fromValue:0
                                                       toValue:(sixDegreesOfRadians)];

secondHandRotation.duration = 1;
secondHandRotation.cumulative = YES;
secondHandRotation.repeatCount = 10000;

[secondHand.layer addAnimation:secondHandRotation forKey:@"rotationAnimation"];

This behaves exactly as expected, however, the second hand always starts at 12 O Clock on the clock face. I would like to start at an arbitrary position. For example, if the current value of "seconds" is 30 seconds, I would like to rotate the secondHand by 180 degrees before I show the clock and start animating it.

I've tried this by adding (before the animation):

float initialSecondHandTransform= degreesToRadians(currentTimeComponents.second * 6);
[secondHand setTransform:CGAffineTransformMakeRotation(initialSecondHandTransform)];

But this causes the second hand to jump randomly around the clock face once a second. I've attempted to set the fromValue to the initialMinuteHandTransform value, and/or tried changing the toValue to initialMinuteHandTransform + sixDegreesOfRadians but I still get erratic movement.

How can I start secondHand at an arbitiary position, and animate it by 6 degrees of rotation (a second on the clock face) once per second, indefinitely?

Upvotes: 0

Views: 844

Answers (1)

David Rönnqvist
David Rönnqvist

Reputation: 56635

You are missing the additive property. It configures the animation to add the animation value to the existing value (a relative animation).

secondHandRotation.additive = YES;

That way the animation is going to start from the current rotation.

If you would have used a CABasicAnimation you could have used the byValue property instead of toValue and fromValue.

Upvotes: 1

Related Questions