Skip navigation.
 
mlUsing Core Animation to Animate NSSplitView Collapse
FROM : Jonathan Dann
DATE : Wed Mar 26 18:12:32 2008

Hi All,

I've managed to do the above with NSAnimation, but I'm trying to do 
the same using Core Animation.

AFAIK To hide a split view pane when the user clicks a button, you 
need to set the frame's height/width to zero and move the divider when 
the animation has finished.  When using an implicit animation on the 
view's frame I can't see how to get a notification that the animation 
has ended.  If I do the following:

// horizontal splitView
[[subview animator] setFrame:newFrame];
[splitView setPosition:[splitView maxPossiblePositionOfDividerAtIndex:
0]  ofDividerAtIndex:0];

the animation is not shown as the divider causes the subview to 'snap' 
shut immediately.  With NSAnimation you can set the delegate and move 
the split view bar in the -animationDidEnd: method.

To do the same with Core Animation I've tried to set up my own 
CABasicAnimation, but I can't get it to work, and the Programming 
Guide isn't clearing up the matter for me.  I've tried this so far:

- (IBAction)hide:(id)sender {
       NSScrollView *scrollView = self.splitView.subviews.secondObject; // -
secondObject is my own NSArray method and the scrollView is the lower 
of a horizontal two-pane split view;

   NSRect toValue = scrollView.frame;
   toValue.size.height = 0.0;

   CABasicAnimation *hidePaneAnimation = [CABasicAnimation 
animationWithKeyPath:@"position"];
   [hidePaneAnimation setRemovedOnCompletion:NO];
   [hidePaneAnimation setFillMode:kCAFillModeForwards];
   [hidePaneAnimation setToValue:[NSValue valueWithRect:toValue]];
   [hidePaneAnimation setFromValue:[NSValue valueWithRect:[scrollView 
frame]]];
   [hidePaneAnimation setDelegate:self];
   [scrollView setWantsLayer:YES];
   [scrollView setLayer:[CALayer layer]];
   [[scrollView layer] addAnimation:hidePaneAnimation 
forKey:@"positionAnimation"];
}

- (void)animationDidStop:(CAAnimation *)animation finished:
(BOOL)finished;
{
   NSLog(@"%p %s %@ Finished: %i",self,__func__,animation,finished);
   NSString *keyPath = [(CABasicAnimation *)animation keyPath];
   NSLog(@"key %@",keyPath);
   NSSplitView *splitView = (NSSplitView *)self.view;
   CALayer *layer = [splitView.subviews.secondObject layer];
   [layer setValue:[(CABasicAnimation *)animation toValue] 
forKeyPath:keyPath];
   [layer removeAnimationForKey:keyPath];
   [splitView setPosition:[splitView maxPossiblePositionOfDividerAtIndex:
0] ofDividerAtIndex:0];
}

Currently this just causes the pane to snap shut and flicker a 
little.  Can anybody give me a hand with this, please?  I've tried 
getting the default CABasicAnimation for setting a view's frame 
instance by sending my subview -animationForKey:@"frame", but this 
just retuns nil.  Interestingly, passing the key @"hidden" returns an 
animation instance.

Thanks,

Jonathan

Related mailsAuthorDate
No related mails found.