Rotate an Image with Animation – Part 1

Editor’s Note: Part 2 of this post shows how rotate an images, buttons and other UI objects up to 360 degrees as well as rotating objects clockwise or counter-clockwise.

Last week I wrote a tip to demonstrate how to move an image on screen using animation. In this post I’ll show how to rotate an image with animation. One thing to cover as it relates to rotation is conversion of degrees to radians. Although most of us think in terms of degrees when it comes to rotating objects, the libraries we’ll access require rotation to be specified in radians.

Radians and Degrees

A circle is 360 degrees, which translates to 2Π radians. Thus, to convert from degrees to radians, we’ll need these definitions:

// This is defined in Math.h
#define M_PI   3.14159265358979323846264338327950288   /* pi */
 
// Our conversion definition
#define DEGREES_TO_RADIANS(angle) (angle / 180.0 * M_PI)

Follow this link to read more about the relationship between degrees and radians.

Method To Rotate an Image

The rotateImage method takes four parameters – the image to rotate, duration of the animation in seconds, the animation curve to apply, and the degrees to rotate. Here is how the method looks:

- (void)rotateImage:(UIImageView *)image duration:(NSTimeInterval)duration 
       curve:(int)curve degrees:(CGFloat)degrees
{
  // Setup the animation
  [UIView beginAnimations:nil context:NULL];
  [UIView setAnimationDuration:duration];
  [UIView setAnimationCurve:curve];
  [UIView setAnimationBeginsFromCurrentState:YES];
 
  // The transform matrix
  CGAffineTransform transform = 
      CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(degrees));
  image.transform = transform;
 
  // Commit the changes
  [UIView commitAnimations];
}
Calling the Rotate Method

First thing to note is that a positive value for the degrees will rotate clockwise – a negative will rotate counter-clockwise. Calling the rotate method is as simple as shown below:

 
- (void)startApp
{
  UIImageView *imageToMove =
     [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"ArrowUp.png"]];
  imageToMove.frame = CGRectMake(10, 10, 20, 100);
  [self.view addSubview:imageToMove];
 
  [self rotateImage:imageToMove duration:3.0 
      curve:UIViewAnimationCurveEaseIn degrees:180];
 
  ...
 
}

16 Comments

  1. I seem to be having trouble with this code. When I call rotateImage:…. and I use 360 degrees it doesn’t move at all. Shouldn’t it spin in a full circle? And when I put 270 degress it spins -90. How can I make it so the image spins in a full circle twice?

  2. Hi,
    I want to rotate relative it’s corner not center, how can I do?

    • you have to change the .anchorPoint PROPERTY
      and make it different than the (0.5,0.5) which is the center

  3. Thanks a lot for this post. It was really helpful.

    I am actually building a script to rotate an image back and forth about 45 degrees in an NSTimer.

    Thanks for the code snippets. :)

  4. Hi !
    I’ve tested the code you gave.
    I’ve changed the angle of rotation (in radians), and added a function that converts from degrees to radians

    If the angle in degrees is 360 everything is ok
    but if is for example 90 or any number different than 360
    the layer makes the rotation animation and then goes slightly to the start point.

    Why it doesn’t remain at that value of rotation ?

    Thanks

  5. I’ve tested your code you shared with us. I call it in a function to place the iOS info button.

    Im getting a warning for using it on the Botton Image

    incomapttible Objective-C type ‘struct UIButton*, expected “struct UImageView”
    But it is working fine and changes and rotates the infoButton to any requested rotation.

    Any one help out with an explanation why it actually works for this particular implementation:

    UIButton *userInfo = [UIButton buttonWithType:UIButtonTypeInfoLight];
    userInfo.frame = CGRectMake(278, 10, 16, 36);
    userInfo.backgroundColor = [UIColor clearColor];
    [userInfo addTarget:self action:@selector(flipToUsersGuide:)
    forControlEvents:UIControlEventTouchUpInside];
    ……..

    [self rotateImage:iuserInfo duration:0.0 curve:UIViewAnimationCurveEaseIn degrees:-90];
    I am getting Build Warning SDK 4.3 and later
    incomapttible Objective-C type ‘struct UIButton*, expected “struct UImageView”

    // Note setting animation time to zero no need to actually obserserve the rotation in this implementation
    // the current view is set to LanscapeLeft

    Calling your method you have shared in this post

    ———- all is working fine
    – (void)rotateImage:(UIImageView *)image duration:(NSTimeInterval)duration
    curve:(int)curve degrees:(CGFloat)degrees
    {
    // Setup the animation
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:duration];
    [UIView setAnimationCurve:curve];
    [UIView setAnimationBeginsFromCurrentState:YES];

    // The transform matrix
    CGAffineTransform transform = CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(degrees)) ;
    image.transform = transform;

    // Commit the changes
    [UIView commitAnimations];
    }

    • change the method to take a UIButton then. If it works. you’re getting a warning because it’s expected a UIImageView.

  6. How do I have a UIImageView move in a straight line while rotating several times before reaching the destination?
    Thanks
    -Al

  7. Thanks! used this to spin a little gear and toggle the keyboard :)

  8. I use this to make a gauge that shows a value. But it’s part of a navigation controller, and when i leave the gauge’s view, then come back to it, the needle stays where it was when I left the view, and draws ANOTHER needle which rotates to meet the first one. It looks like a pair of scissors closing. How do I remove the old needle before drawing it again? I tried using “release” for that view, but I’m using automatic reference counting and storyboards. Xcode told me I can’t use “release” because of this. Any help would be greatly appreciated. Thanks!

Comments are closed.