Jacopo
Jacopo

Reputation: 1021

Animate NSSplitview and window size

What I'm trying to achieve is that when the user press a button the window grows and the extra space is taken by a panel of NSSplitview that uncollapses and grows to fill the space.

I can easily animate the window resize and the splitview growing independently but when I try to put the two animation together one inevitably happens before the other or by steps. First the window partly resize, then the splitview resize follow, then the window finish resizing and finally the splitview finishes as well. Any ides on why that might be happening?

Here is the code I use:

- (IBAction)helpButtonPressed:(id)sender
{
   if ([sender isKindOfClass:[NSMenuItem class]]) [sender setState:![sender state]];
   NSWindow *window = [[[self windowControllers] objectAtIndex:0] window];
   NSRect oldFrame = [window frame];
   CGFloat windowWidthAdd;

   if ([sender state]) windowWidthAdd = HELP_WIDTH; else windowWidthAdd = -HELP_WIDTH;    
   NSRect newFrame = NSMakeRect(oldFrame.origin.x, oldFrame.origin.y,oldFrame.size.width+windowWidthAdd, oldFrame.size.height);

   [[NSAnimationContext currentContext] setDuration:0.3f];
   [NSAnimationContext beginGrouping];
   [[window animator] setFrame:newFrame display:YES];
   if ([sender state]) [self uncollapseRightView]; else [self collapseRightView];
   [NSAnimationContext endGrouping];

}

-(void)collapseRightView
{
    NSView *right = [[self.splitView subviews] objectAtIndex:1];
    NSView *left  = [[self.splitView subviews] objectAtIndex:0];
    NSRect leftFrame = [left frame];
    NSRect overallFrame = [self.splitView frame];
    [right setHidden:YES];
    [[left animator] setFrameSize:NSMakeSize(overallFrame.size.width,leftFrame.size.height)];
}

-(void)uncollapseRightView
{
    NSView *left  = [[self.splitView subviews] objectAtIndex:0];
    NSView *right = [[self.splitView subviews] objectAtIndex:1];
    [right setHidden:NO];
    CGFloat dividerThickness = [self.splitView dividerThickness];
    // get the different frames
    NSRect leftFrame = [left frame];
    // Adjust left frame size
    leftFrame.size.width = (leftFrame.size.width-HELP_WIDTH-dividerThickness);
    NSRect rightFrame = [right frame];
    rightFrame.origin.x = leftFrame.size.width + dividerThickness;
    rightFrame.size.width = HELP_WIDTH;
    [[left animator] setFrameSize:leftFrame.size];
    [[right animator] setFrame:rightFrame];
}

Upvotes: 0

Views: 686

Answers (1)

Jacque
Jacque

Reputation: 820

If you are looking a little closer at the class reference of NSSplitView, you will recognize it conforms to NSAnimatablePropertyContainer. That means NSSplitView will provide you with an "animating proxy of itself". If you call animator on your NSSplitView you'll get this proxy, on which you should be able to change properties in an animated fashion.

For adjusting the animation duration and timing function, use NSAnimationContext the same way you already did.

Last but not least: Did you recognize NSSplitView's minPossiblePositionOfDividerAtIndex: and maxPossiblePositionOfDividerAtIndex:?

Upvotes: 0

Related Questions