2

I need help with CABasicAnimation. I am trying to move a NSView left by 300 pixels. I found this SO thread: How to animate the frame of an layer with CABasicAnimation?

Turns out animating the frame is not possible and one of the answer points to a link to QA on Apple's website but it takes me a to a generic page: http://developer.apple.com/library/mac/#qa/qa1620/_index.html

So, how can I do something as simple as translation of my NSView/CALyer? Thanks!

Community
  • 1
  • 1
0xSina
  • 20,973
  • 34
  • 136
  • 253

2 Answers2

4

NSView has a protocol called NSAnimatablePropertyContainer which allows you to create basic animations for views:

The NSAnimatablePropertyContainer protocol defines a way to add animation to an existing class with a minimum of API impact ... Sending of key-value-coding compliant "set" messages to the proxy will trigger animation for automatically animated properties of its target object.

The NSAnimatablePropertyContainer protocol can be found here

I recently used this technique to change the origin of a frame:

-(void)setOrigin:(NSPoint)aPoint {
    [[self animator] setFrameOrigin:aPoint];
}

Instead of calling the [view setFrameOrigin:], I created another method called setOrigin: which then applies the setFrameOrigin: call to the view's animator.

If you need to change the duration of the animation, you can do so like this (similar to CATransactions):

-(void)setOrigin:(NSPoint)aPoint {
    [NSAnimationContext beginGrouping];
    [[NSAnimationContext currentContext] setCompletionHandler:^{
        ...Completion Callback Code goes here...
    }];
    [[NSAnimationContext currentContext] setDuration:1.0];
    [[self animator] setFrameOrigin:aPoint];
    [NSAnimationContext endGrouping];
}

The NSAnimationContext is described here

C4 - Travis
  • 4,502
  • 4
  • 31
  • 56
  • The reason why I am using CABasicAnimation is because I need a callback for when the animation ends – 0xSina Mar 14 '12 at 10:26
  • In the NSAnimationContext documentation, you can check the – setCompletionHandler: method which lets you set a callback. – C4 - Travis Mar 14 '12 at 16:59
0

You can animate center property instead. Eg:

//assuming view is your NSView
CGPoint newCenter = CGPointMake(view.center.x - 300, view.center.y);
CABasicAnimation *animation = [CABasicAnimation animation];
//setup your animation eg. duration/other options
animation.fromValue = [NSValue valueWithCGPoint:v.center];
animation.toValue = [NSValue valueWithCGPoint:newCenter];
[view.layer addAnimation:animation forKey:@"key"];
ksh
  • 1,894
  • 19
  • 20
  • thanks for the input. Will try this out. Just curious, why are we not passing in key path when initializing? "animationWithKeyPath:" – 0xSina Mar 12 '12 at 07:48
  • Well we don't need it here, it's useful mostly for transformations, when we don't want to construct fullblown CATransform3D but rather say "animate `translation.x` from value 0 to value 10". – ksh Mar 12 '12 at 07:57
  • This is incorrect. Layer-backed NSView owns its layer, you should consider it an implementation detail. You should not touch backing layer or add animations directly to it. NSAnimatablePropertyContainer is a way to go. – Konstantin Pavlikhin Sep 28 '16 at 09:41