views:

295

answers:

2

I have this view and I do some rotation transformation to it using something like

myView.transform = CGAffineTransformMakeRotation(degreesToRadian(90));
//The view was originally at 0 degrees.

at some other point of my code, I would like to scale the view animating it, so I do

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.0];
myViews.transform = CGAffineTransformMakeScale(2.0f, 2.0f);
[UIView commitAnimations];

but when I do that the animation is performed as the view is at 0 degrees, ignoring the previous transformation. It simply assumes as the view is yet at zero degrees, so, this animation scales the view and rotates it back to 0 degrees (!!!!?????)

Is this some bug or am I missing something? thanks.

+2  A: 
KennyTM
Thanks, but this solves the rotation problem but creates the scale problem. The problem is this: I have 4 zooms factors I use for this view, something like 0.66, 1.0, 1.5 and 2.0. These are absolute values. If I use your solution it will be impossible to return back to each zoom factor....
Digital Robot
@Mike: Why can't you use an independent ivar to store the zoom factor?
KennyTM
What I mean is this: suppose the zoom factor is at 1. then I use your solution and go to 0.66. Now I want to go to 2. Using the absolute scale, I just put the zoomFactor as 2, but now the zoom factor will have to be 3.03. To go back to 0.66 now, I will have to make it 0.21. After zillions of transformations I will not know what is the zoom factor now. I will have to keep a history of all applied transformations to know the current zoom factor, just looking at the ivar.... there's no way to apply the transformation to a view and make it permanent? I mean, to update the transformation matrix?
Digital Robot
@Mike: So store the original transform, and call `CGAffineTransformScale(original_transform, 2.0f, 2.0f);`. The 1st argument of CGAffineTransformScale can take any CGAffineTransform.
KennyTM
If I do that, I will have the original rotation problem back. Remember that the original transform represents the view before the rotation I did (see my question). BTW, the rotation needs to be absolute too.
Digital Robot
@Mike: What I mean is `CGAffineTransformScale(CGAffineTransformMakeRotation(degreesToRadian(90)), 2, 2);`.
KennyTM
sorry, but this will not solve too, because you are using relative scale and all the problems I mentioned will appear. I have discovered the best solution and posted as answer. +1 for the effort! :-)
Digital Robot
@Mike: The end result of your solution should be the same as what Kenny suggested, given that CGAffineTransformScale concatenates the scale transform and the rotation transform you passed in (unless I have the order of the concatenation wrong).
Brad Larson
not true, if you look my answer you will see both my transforms are absolute, not relative. Kenny's solution is an absolute rotation inside a relative translation.
Digital Robot
+1  A: 

After discussing with KennyTM, I arrived at the best solutions for having both absolute transformations...

on the zoom method, I do:

// notice that both transformations are absolute
CGAffineTransform rotation = CGAffineTransformMakeRotation(degreesToRadian(viewAngle));
CGAffineTransform zoom = CGAffineTransformMakeScale(zoomFactor, zoomFactor);
myView.transform = CGAffineTransformConcat(rotation, zoom);

I store viewAngle when I rotate the view.

Digital Robot