views:

2612

answers:

4

Sorry if this is obvious or covered elsewhere, but i've been googling all day and haven't found a solution that actually worked.

My problem is as follows: I am currently drawing an image in a full screen UIView, for examples sake we'll say the image is in the bottom right corner of the UIView. I'd like to do a rotation transform(CGAffineTransformMakeRotation) at the center of that image, however, by default the rotation command rotates around the center of the UIView it self. As a result, my image moves around the screen when i rotate instead of it staying in place and rotating around its own center.

From what i've gathered, i need to translate my context so that the origin(center of the UIView) is at the center of my image, Rotate, and then restore the context by translating back to the original spot.

The following is the closest thing i've gotten to work, but the problem is that while the image is rotating, it moves downward while it's rotating. I think this is caused by animation tweening the 1st step translate and 3rd step translate instead of just realizing that the beginning and end point on the translates would be the same...

// Before this i'd make a call to a function that draws a path to a passed in context
CGAffineTransform inverseTranslation = CGAffineTransformMakeTranslation( transX, transY );
CGAffineTransform translation = CGAffineTransformMakeTranslation( -transX, -transY );
CGAffineTransform rot = CGAffineTransformMakeRotation( 3.14 );
CGAffineTransform final = CGAffineTransformConcat( CGAffineTransformConcat( inverseTranslation, rot ), translation );
// Then i apply the transformation animation like normal using self.transform = final etc etc

I've also tried stuff like CGContextTranslateCTM and CGContextSaveGState/UIGraphicsPushContext, but these seem to have little effect.

I've been fighting with this for days and my current solution seems close, but i have no clue how to get rid of that translating tweening. Does anyone have a solution for this or a better way to go about this?

[update] For the time being i'm drawing my image centered at the UIview's center and then setting the UIView.center property to the origin i'd like to rotate and then doing the rotate command. Seems like a bit of a hack, but until i can get the real translates working it's my only choice. Thanks!

+1  A: 

Rotation happens around the anchorPoint of the view's layer. The default for the anchorPoint is the center (0.5, 0.5), so the rotation alone without the translations should suffice.

Did a quick test and this works for me:

[UIView beginAnimations:@"rotate" context:nil];
self.transform = CGAffineTransformMakeRotation( 45. / 180. * 3.14 );
[UIView commitAnimations];
duncanwilcox
Perhaps my description was a bit misleading. I am drawing something on a context(I called it an image, but it's just something i draw using context commands) and it is not at the cetner of the context. I want to rotate as if the center of the context were at the center of my "image".
Skyler
+1  A: 

If you don't want an animation to occur, but just set the new rotation, you can use this:

CGFloat newRotation = 3.14f 

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.0]; // no tweening
CGAffineTransform transform = CGAffineTransformMakeRotation(newRotation);
self.transform = transform;
[UIView commitAnimations];

The rotation should indeed take place around the center of the UIView. Setting the animationDuration to zero garantees no tweening should happen.

Be sure though you don't do this 60 times a second. It's very tempting to create game like animations with these tools. These kind of animations aren't exactly meant for a frame to frame based, "lots of sprites flying everywhere" game.

For that - and I've been down that road - the only way to go, is OpenGL.

Kriem
Well i do want animation for the rotate, perhaps i can use your 0 sec duration for the pre and post translates since CGContextTranslateCTM didn't seem to work...
Skyler
Make sure you save the CGContext state before doing the CGContextTranslateCTM. Then restore the state. It has no (apparent) effect if you just translate the CTM after drawing in your context.
Kriem
+3  A: 

duncanwilcox' answer is the right one, but he left out the part where you change the anchor of the view's layer to the point you want to rotate around.

CGSize sz = theview.bounds.size;
// Anchorpoint coords are between 0.0 and 1.0
theview.layer.anchorPoint = CGPointMake(rotPoint.x/sz.width, rotPoint.y/sz.height);
[UIView beginAnimations:@"rotate" context:nil];
theview.transform = CGAffineTransformMakeRotation( 45. / 180. * 3.14 );
[UIView commitAnimations];

This is documented here: http://developer.apple.com/documentation/Cocoa/Conceptual/CoreAnimation_guide/Articles/Layers.html

n8gray
A: 

Hi All,

I have similar problem. I have drawn lines and curves in a view.and now i wanted to rotate that line and curves around it's own center. Below is the link for the screenshot, where you can see white colored object which i want to rotate. [1]: http://elanoffice.dyndns.org/myelan/PMS/1521%5FPicture 1.png.zip I am not getting how to achieve it. I have also tried above solutions.But it's not working for me. Any kind of help will be appreciated.

Thanks, Dhaval

dhaval