Rotate an Image or Button with Animation – Part 2

In a previous post Rotate an Image with Animation – Part 1 I wrote a short code block using CGAffineTransform to rotate an image. Problem is, if you want to rotate an image 360 degrees, or repeat a rotation a specified number of times, you’ll need to take a different approach, which is the focus of this post. This code example will use a layer for animation so this same effect can used on images, buttons, etc.

The video below shows a rotating a button (on the left) as well as image. Notice the direction of rotation is clockwise on the button and counter-clockwise on the image. Also, notice that the rate of the spin is different for each object.

Spin/Rotate Code

This method accepts a layer object (CALayer), the duration of the spin (in seconds) and the direction:

- (void)spinLayer:(CALayer *)inLayer duration:(CFTimeInterval)inDuration
     direction:(int)direction
{
  CABasicAnimation* rotationAnimation;
 
  // Rotate about the z axis
  rotationAnimation = 
    [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
 
  // Rotate 360 degress, in direction specified
  rotationAnimation.toValue = [NSNumber numberWithFloat: M_PI * 2.0 * direction];
 
  // Perform the rotation over this many seconds
  rotationAnimation.duration = inDuration;
 
  // Set the pacing of the animation
  rotationAnimation.timingFunction = 
    [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
 
  // Add animation to the layer and make it so
  [inLayer addAnimation:rotationAnimation forKey:@"rotationAnimation"];
}
Calling the spinLayer Method

The code below shows how to call the method, specifying the duration and the direction. Make note that the layer associated with the image/button is passed in to the method:

#define SPIN_CLOCK_WISE 1
#define SPIN_COUNTERCLOCK_WISE -1
 
UIImageView  *testImage;
...
[self spinLayer:testImage.layer duration:1 direction:SPIN_CLOCK_WISE];
 
UIButton *infoButton;
...
[self spinLayer:infoButton.layer duration:3 direction:SPIN_COUNTERCLOCK_WISE];
Spin Effect – Timing Functions

Notice in the original example I specified kCAMediaTimingFunctionEaseInEaseOut as the timing function name, which defines the pacing of the animation, in this case, the animation begins slowly, accelerates and then slows again.

You can experiment with the following timing functions for various effects:

kCAMediaTimingFunctionLinear
kCAMediaTimingFunctionEaseIn
kCAMediaTimingFunctionEaseOut
kCAMediaTimingFunctionEaseInEaseOut
kCAMediaTimingFunctionDefault

  1. Thanks for the code. In y rotation, button is split in two parts and from center around y axis, and I cant see the half of the button, only one half is animating. This occurs when I use an UIImageView as background of button. Anybody has an idea?

  2. I would like to implement your code in a way that the image flips vertically instead of rotate – How can I achieve that?

  3. @ windrago

    you should try duration to 0 and put angle of rotation to this
    rotationAnimation.toValue = [NSNumber numberWithFloat: M_PI * direction];

    Above code is untested.

  4. I’m missing something but i don’t know what. Still beginner xcode programmer. I get an error saying Request for member ‘layer’ in something not a structure or union. I added the #import and added the layer to my button.

  5. How to stop the image from returning to its start position? Just want it to stop if it spins a random number of turns and then be able to give it another spin.

  6. This doesn’t work if the view is already rotated initially.

  7. Hi guys, how can i make my image remain in the position given by the rotation angle?
    it keeps going back to the defalut position (0 degrees), and i want the animation to be completed at 45 degrees, so the image must stay at 45 degrees, not return to 0.

    Thanks!!

    • Hi, let me know if you accomplished this, I’m interested on doing the same.

      Thanks

Comments are closed.