Jack Humphries
Jack Humphries

Reputation: 13267

Rotating NSView around center

I'm trying to animate the rotation of an NSView around its center, but it keeps shifting side to side during rotation. What is causing this?

-(void)startRefreshAnimation {

    [NSAnimationContext beginGrouping];
    [[NSAnimationContext currentContext] setDuration:1.0];
    [[NSAnimationContext currentContext] setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
    [NSAnimationContext currentContext].completionHandler = ^{ [self startRefreshAnimation]; };
    [[view animator] setFrameCenterRotation:previousRotation - 90.0];
    previousRotation += -90.0;
    [NSAnimationContext endGrouping];

}

Shift up during rotation:

enter image description here

Shift down during rotation:

enter image description here

Upvotes: 3

Views: 5384

Answers (2)

Vikas Bansal
Vikas Bansal

Reputation: 11740

here is the dummy project and the answer that I found. (For Cocoa Applicaiton)

Rotate NSImageView

github project (download)

Upvotes: 2

Justin Meiners
Justin Meiners

Reputation: 11113

From the documentation:

If the application has altered the layer’s anchorPoint property, the behavior is undefined. Sending this message to a view that is not managing a Core Animation layer causes an exception.

https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ApplicationKit/Classes/NSView_Class/Reference/NSView.html

Is your view managing a CALayer with an unmodified anchor point?

EDIT

I setup similar code at got the exact same results. No adjust of origin or anchor point could resolve this problem. My theory is that this particular method contains bugs (does for autolayout), or works in a way which we don't anticipate. I achieved the correct effect using CABasicAnimation.

/* setup */

....
     _view.layer.anchorPoint = CGPointMake(0.5f, 0.5f);
     _view.layer.position = ...

    [self startRefreshAnimation];
}

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
    [self startRefreshAnimation];
}

-(void)startRefreshAnimation {

    CABasicAnimation *anim2 = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
    anim2.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
    anim2.fromValue = [NSNumber numberWithFloat:previousRotation * (M_PI / 180.0f)];
    anim2.toValue = [NSNumber numberWithFloat:(previousRotation + 90.0f) * (M_PI / 180.0f)];
    previousRotation = previousRotation + 90.0f;
    anim2.duration = 1.0f;
    anim2.delegate = self;
    [_view.layer addAnimation:anim forKey:@"transform"];
}

Upvotes: 1

Related Questions