views:

2560

answers:

3

Hi there!

I'm trying to create a very simple keyframe animation, whereby a graphic Rotates from one angle to another, through a given midpoint.

(The purpose is to be able to animate rotation through an OBTUSE angle of arc GREATER THAN 180 DEGREES, rather than having the animation 'cheat' and go the shortest route, i.e., via the opposite , ACUTE smaller angle -- which can happen when there's only one [i.e, destination] keyframe. To go the 'long' way around, I assume I need an extra keyframe midway through, along the desired arc.)

Here's what I've got so far (which does get the graphic to the desired rotation, via the most acute angle):

#define DEGREES_TO_RADIANS(__ANGLE__) ((__ANGLE__) / 180.0 * M_PI)

...

[UIView beginAnimations:nil context:nil];
CGAffineTransform cgCTM = CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(desiredEndingAngle));
[UIView setAnimationDuration:0.5];
graphic.transform = cgCTM;
[UIView commitAnimations];

As I understand it, I’m not looking for animation along a Path (since that’s for Translation, rather than Rotation) ...

Anyway, any help would be VERY much appreciated! Thanks in advance.

A: 

Try this:

UIImageView* rotatingImage = [[UIImageView alloc] init]];
[rotatingImage setImage:[UIImage imageNamed:@"someImage.png"]];

CATransform3D rotationTransform = CATransform3DMakeRotation(1.0f * M_PI, 0, 0, 1.0);
CABasicAnimation* rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];

rotationAnimation.toValue = [NSValue valueWithCATransform3D:rotationTransform];
rotationAnimation.duration = 0.25f;
rotationAnimation.cumulative = YES;
rotationAnimation.repeatCount = 1;

[rotatingImage.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"];
Nathan de Vries
Hi, Nathan! Thanks so much for the response and your expertise. I'm getting the following Error on the last line: "request for member 'layer' in something not a structure or union". I imagine I'm missing some other setup (as UIImage doesn't normally have a Layer property). Being brand new to Core Animation, am still a bit stuck. [Also not sure as yet how this specifies a midpoint, or alternatively, a DIRECTION for the rotation (essentially a choice of Clockwise or Counterclockwise), but I'm sure it'll become apparent once I can get this to run.] Many thanks to you/all for any add'l help!
I fixed the code sample -- I was adding the animation to the UIImage instead of a UIImageView containing a UIImage, which won't work for obvious reasons :-)
Nathan de Vries
This SO question might give you a few practical hints about how to use CAKeyframeAnimation: http://stackoverflow.com/questions/929364/how-to-create-iphones-wobbling-icon-effect
Nathan de Vries
Will check it out. Thanks so much, Nathan!
+3  A: 

Think I’ve got it.

Here’s code which does (in this example) a full 270 DEGREE rotation (1.5*pi radians), including various parameters that can be customized further:

CALayer *layer = rotatingImage.layer;
CAKeyframeAnimation *animation;
animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"];
animation.duration = 0.5f;
animation.cumulative = YES;
animation.repeatCount = 1;
animation.values = [NSArray arrayWithObjects:    // i.e., Rotation values for the 3 keyframes, in RADIANS
   [NSNumber numberWithFloat:0.0 * M_PI], 
   [NSNumber numberWithFloat:0.75 * M_PI], 
   [NSNumber numberWithFloat:1.5 * M_PI], nil]; 
animation.keyTimes = [NSArray arrayWithObjects:     // Relative timing values for the 3 keyframes
   [NSNumber numberWithFloat:0], 
   [NSNumber numberWithFloat:.5], 
   [NSNumber numberWithFloat:1.0], nil]; 
animation.timingFunctions = [NSArray arrayWithObjects:
   [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn], // from keyframe 1 to keyframe 2
   [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut], nil]; // from keyframe 2 to keyframe 3
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;

[layer addAnimation:animation forKey:nil];

Thanks!

A: 

This is exactly what I been looking for, in my case I wanted to rotate something by 360 degres and nothing was happening. It took something to realize that core animation is lazy and takes the shortes route (which in my case is 0 degrees) lol. Thanks rond!

nacho4d