1

I am trying to find a way to programmatically resize NSSplitViewItems.

Say the NSWindow frame size is 500x500px. masterViewItem has a width of 100px, while subViewItem has a width of 400px.

When FOO, I want masterViewItem to collapse to 0px (towards the left), while subViewItem expands to fill the entire window (500px).

When BAR, I want masterViewItem to expand back to 100px, while subViewItem collapses back to the original 400px.

- (IBAction) onTapOnSomeButton:(NSButton *)sender {

    NSWindow *window = [[NSApplication sharedApplication] mainWindow];
    NSSplitViewController *splitViewController = (NSSplitViewController *)[window contentViewController];
    NSSplitViewItem *masterViewItem =[splitViewController.splitViewItems firstObject];
    NSSplitViewItem *subViewItem = [splitViewController.splitViewItems lastObject];
    if (FOO) {
        [NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
            //    Expand subViewItem 
        } completionHandler:^{
        }];
    } else if (BAR) {
        [NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
            //    Expand masterViewItem while shrinking subViewItem
        } completionHandler:^{
        }];
    }
}

I am able to animate each item so that it seems to collapse/expand, i.e.

subViewItem.viewController.view.animator.frame = CGRectMake(0, 0, window.frame.size.width, subViewItem.viewController.view.frame.size.height);

but the divider will not move, making the two items just move individually, and does not look like the entire screen is collapsing/expanding.

How would I implement this? Thanks in advance.

UPDATE

So I have done a bit more research, and found this:

How to animate the NSSplitView while resizing?

So I made code like this:

- (IBAction) onTapOnSomeButton:(NSButton *)sender {
    NSWindow *window = [[NSApplication sharedApplication] mainWindow];
    NSSplitViewController *splitViewController = (NSSplitViewController *)[window contentViewController];
    NSSplitViewItem *masterViewItem =[splitViewController.splitViewItems firstObject];
    NSSplitViewItem *subViewItem = [splitViewController.splitViewItems lastObject];
    if (FOO) {
         NSMutableDictionary *collapseMainAnimationDict = [NSMutableDictionary dictionaryWithCapacity:2];
         [collapseMainAnimationDict setObject: subView forKey:NSViewAnimationTargetKey];
         NSRect newRightSubViewFrame = subView.frame;
         newRightSubViewFrame.size.width =  splitViewController.splitView.frame.size.width;
         [collapseMainAnimationDict setObject:[NSValue valueWithRect:newRightSubViewFrame] forKey:NSViewAnimationEndFrameKey];

         NSMutableDictionary *collapseInspectorAnimationDict = [NSMutableDictionary dictionaryWithCapacity:2];
         [collapseInspectorAnimationDict setObject: masterView forKey:NSViewAnimationTargetKey];
         NSRect newLeftSubViewFrame = masterView.frame;
         newLeftSubViewFrame.size.width = 0.0f;
         newLeftSubViewFrame.origin.x = splitViewController.splitView.frame.size.width;
         [collapseInspectorAnimationDict setObject:[NSValue valueWithRect:newLeftSubViewFrame] forKey:NSViewAnimationEndFrameKey];

         NSViewAnimation *collapseAnimation = [[NSViewAnimation alloc] initWithViewAnimations:[NSArray arrayWithObjects: collapseMainAnimationDict, collapseInspectorAnimationDict, nil]];
         [collapseAnimation setDuration:0.3f];
         [collapseAnimation startAnimation];
         [splitViewController.splitView adjustSubviews];
         [splitViewController.splitView setNeedsDisplay: YES];
    } else if (BAR) {
        // Not yet implemented
    }
}

But to no effect. Any suggestions?

Community
  • 1
  • 1
Naoto Ida
  • 1,275
  • 1
  • 14
  • 29

2 Answers2

1

You have to resize the panes using [NSSplitView setPosition:ofDividerAtIndex:].

I have no idea what NSSplitViewController is, but presumably you can get access to the NSSplitView via its view property, or some such.

Droppy
  • 9,691
  • 1
  • 20
  • 27
1

Rather than looking at it as a resize, it sounds like you're simply trying to collapse/uncollapse the master view item. You can just use NSSplitViewItem's collapsed property with its animator proxy to trigger the collapse:

    if (FOO) {
        //    Expand subViewItem (collapse the master view item)
        masterViewItem.animator.collapsed = YES;

And uncollapse:

    } else if (BAR) {
        //    Expand masterViewItem while shrinking subViewItem
        masterViewItem.animator.collapsed = NO;
    }
}

With 10.11, there's API to designate your master view item as a "sidebar", which has additional collapse/uncollapse behavior for that item (such as overlays).

Taylor
  • 3,183
  • 17
  • 18
  • Thanks. I have tried that, but cannot find the correct code to expand the width of `subViewItem.viewController.view`, while retaining the overall window size. Any suggestions? – Naoto Ida Jul 01 '15 at 07:06
  • That should happen automatically/be controlled by the `holdingPriority` of the subViewItem (which is the priority the split view holds the items at their current size) and any other constraints you have in it. If the `holdingPriority` is less than `NSLayoutPriorityWindowSizeStayPut` (500), and there are no other constraints that would prevent it from growing larger, then it will as the master item collapses. – Taylor Jul 01 '15 at 14:12
  • Sorry, I'm taking over someone else's work, so I'm confused in some parts. There was a self.preferredContentSize set, and by removing it, I could collapse the masterViewItem without changing the width of the window, but there is not animation when subViewItem fills the void. – Naoto Ida Jul 02 '15 at 05:12