Search code examples
objective-cmacoscocoacore-animationquartz-2d

How do I achieve continuous rotation of an NSImage inside NSImageView?


FUTURE VIEWERS:

I have managed to finish this rotation animation and code with description can be found on tho question. NSImage rotation in NSView is not working

Before you proceed please up vote Duncan C 's answer. As I manage to achieve this rotation from his answer.


I have an image like this,

enter image description here

I want to keep rotating this sync icon, On a different thread. Now I tried using Quartz composer and add the animation to QCView but it is has very crazy effect and very slow too.

Question :

How do I rotate this image continuously with very less processing expense?

Effort

I read CoreAnimation, Quartz2D documentation but I failed to find the way to make it work. The only thing I know so far is, I have to use

  • CALayer
  • CAImageRef
  • AffineTransform
  • NSAnimationContext

Now, I am not expecting code, but an understanding with pseudo code will be great!


Solution

  • Getting an object to rotate more than 180 degrees is actually a little bit tricky. The problem is that you specify a transformation matrix for the ending rotation, and the system decides to rotate in the other direction.

    What I've done is to create a CABasicAnimation of less than 180 degrees, set up to be additive , and with a repeat count. Each step in the animation animates the object more.

    The following code is taken from an iOS application, but the technique is identical in Mac OS.

      CABasicAnimation* rotate =  [CABasicAnimation animationWithKeyPath: @"transform.rotation.z"];
      rotate.removedOnCompletion = FALSE;
      rotate.fillMode = kCAFillModeForwards;
    
      //Do a series of 5 quarter turns for a total of a 1.25 turns
      //(2PI is a full turn, so pi/2 is a quarter turn)
      [rotate setToValue: [NSNumber numberWithFloat: -M_PI / 2]];
      rotate.repeatCount = 11;
    
      rotate.duration = duration/2;
      rotate.beginTime = start;
      rotate.cumulative = TRUE;
      rotate.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
    

    CAAnimation objects operate on layers, so for Mac OS, you'll need to set the "wants layer" property in interface builder, and then add the animation to your view's layer.

    To make your view rotate forever, you'd set repeat count to some very large number like 1e100.

    Once you've created your animation, you'd add it to your view's layer with code something like this:

    [myView.layer addAnimation: rotate forKey: @"rotateAnimation"];
    

    That's about all there is to it.