10

I am rotating a view with this:

CGAffineTransform rotatedTransform = CGAffineTransformRotate(CGAffineTransformIdentity, rotationValue);

I have an object which I want to spin around for about 320 degrees. Now Core Animation is clever and just rotates it as much as needed, doing that by rotating it with -40 degrees. So the object rotates the other way around with a shorter amount of movement.

I want to constrain it to rotate clockwise. Would I have to do that by changing animations in little steps, or is there an more elegant way?

Thanks
  • 40,109
  • 71
  • 208
  • 322

2 Answers2

18

The following snippet rotates a view called someView by using key-framed animation. The animation consists of 3 frames spread over 1 second, with the view rotated to 0º, 180º and 360º in the first, second and last frames respectively. Code follows:

CALayer* layer = someView.layer;
CAKeyframeAnimation* animation;
animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"];

animation.duration = 1.0;
animation.cumulative = YES;
animation.repeatCount = 1;
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;

animation.values = [NSArray arrayWithObjects:
    [NSNumber numberWithFloat:0.0 * M_PI],
    [NSNumber numberWithFloat:0.5 * M_PI],
    [NSNumber numberWithFloat:1.0 * M_PI], nil];

animation.keyTimes = [NSArray arrayWithObjects:
    [NSNumber numberWithFloat:0.0],
    [NSNumber numberWithFloat:0.5],
    [NSNumber numberWithFloat:1.0], nil];

animation.timingFunctions = [NSArray arrayWithObjects:
    [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear],
    [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear], nil];

[layer addAnimation:animation forKey:@"transform.rotation.z"];

If you're after counterclockwise animation, you should use negative values. For a slightly more basic animation, you can use CABasicAnimation:

CALayer* layer = someView.layer;
CABasicAnimation* animation;
animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];

animation.fromValue = [NSNumber numberWithFloat:0.0 * M_PI];
animation.toValue = [NSNumber numberWithFloat:1.0 * M_PI];

animation.duration = 1.0;
animation.cumulative = YES;
animation.repeatCount = 1;
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;

[layer addAnimation:rotationAnimation forKey:@"transform.rotation.z"];
Nathan de Vries
  • 15,481
  • 4
  • 49
  • 55
  • Do I have to include anything special? Xcode complains about all the kCA things like kCAMediaTimingFunctionLinear. They are unknown. – Thanks Jul 21 '09 at 12:11
  • ".objc_class_name_CAKeyframeAnimation", referenced from: literal-pointer@__OBJC@__cls_refs@CAKeyframeAnimation in TestClass.o ld: symbol(s) not found collect2: ld returned 1 exit status – Thanks Jul 21 '09 at 12:15
  • 2
    Whenever you have an issue with something not being found, you should search for it in the documentation to see where it's defined. In this case, those constants are defined in CAMediaTiming & CAMediaTimingFunction which are part of the QuartzCore framework. If you haven't added QuartzCore.framework, that's probably your problem. – Nathan de Vries Jul 21 '09 at 12:47
1

I believe you have to give it another "key frame" if you will to give Core Animation the hint that it needs to go that direction.

Make sure and turn off easing, (at least for the end/beginning of the middle step) otherwise the animation will not look smooth.

Ben Scheirman
  • 40,531
  • 21
  • 102
  • 137