views:

381

answers:

3

I am applying an rotation transform animation in an animation block with this transform:

CATransform3D rotatedTransform = self.layer.transform;
rotatedTransform = CATransform3DRotate(rotatedTransform, 90 * M_PI / 180.0, 0.0f, 0.0f, 1.0f);
self.layer.transform = rotatedTransform;

The animation begins, and the user kicks in another event that would have to push the rotation towards a new target. To calculate realistic looking behavior, I need to know what's the current degrees of the rotation, so that the next rotation degrees can be added up appropriately.

+2  A: 

You can retrieve the current state of an animating layer by grabbing its presentationLayer. Assuming that you have not applied any other transformations to the layer, you can extract the current angle of the rotating layer using code like the following:

CATransform3D rotationTransform = [(CALayer *)[self.layer presentationLayer] transform];
float angle;
if (rotationTransform.m11 < 0.0f)
 angle = 180.0f - (asin(rotationTransform.m12) * 180.0f / M_PI);
else
 angle = asin(rotationTransform.m12) * 180.0f / M_PI;

In an otherwise unmodified transform, the m11 and m12 values are coordinates that lie on the unit circle, so you can use trigonometry to determine the angle they describe.

EDIT (5/18/2009): Added a typecast to CALayer to overcome compiler warnings and fixed the naming of the transform in the trigonometry operations.

Brad Larson
The first line doesn't work. The compiler stops compiling. "Invalid initializer" and "multiple methods found named -transform". Opened up another question for how to get that right. Others on the net (searchengine) seem to have same problemes with getting the values from the presentationLayer.
Thanks
I forgot to add a typecast to CALayer to overcome the compiler warnings. Also, I corrected the references to rotationTransform later in the calculation. I tested this and it works for a rotating view.
Brad Larson
I've set up an action method that's called when I tap a button. Then I ignite the animation with 10 seconds duration, and 180° rotation. The view slowly rotates. As it rotates, I keep klicking the button. The action method executes the code to get the angle, but the angle is 0.0 as long as the animation is going on. When it finished, and I ask again for the angle, I get it: 180.0 ...for some reason that doesn't work during the animation. Just when it's done.
Thanks
I just tried this using the same conditions (10 s rotation of 180 degrees), using the code above to capture the rotation, and was able to get constant updates of the angle as the view was rotating. I enclosed the original rotation in a UIView beginAnimations / commitAnimations block, did you? Are you sending the rotation angle to the console via a log message or how are you reporting it? There must be something else that you are doing differently.
Brad Larson
+3  A: 

This is an old question but I came across this answer while trying to find the current rotation angle during a key frame animation:-

CALayer* layer = [self.layer presentationLayer];
float currentAngle = [[layer valueForKeyPath:@"transform.rotation.z"] floatValue];

Seems to work for me. Also, nice and concise.

Tess Lowe
Perfect. Succinct. This should be accepted as the question's answer.
MikeyWard
A: 

You can also calculate it using matrices and trigonometry. Refer to my answer for this question

Nader