0
votes

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?

1
I am not seeing how you derive your time components... but have you tried logging them? you could also try only running the mod 60 into the degrees to radians method... I don't know why that would matter though.Grady Player
The time is just real time from the system clock. So the user might run my app and the time might be 11:30:45 or 11:20:16. The point is the second hand could need to start anywhere, so I need to transform/rotate it to that angle of rotation, then animate. Thats where i'm having trouble. When I apply a transform, THEN try to animate, the "hand" jumps erratically around the clockface. It currently only works properly if the animation starts with no transform applied to the layer.Dermot

1 Answers

1
votes

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.