objective-ccocoansstackview

NSStackView does not layout views properly


I've just started experimenting with NSStackView, and I'm having a very interesting problem which I can't solve. I've scoured the auto layout guides on Apple's website as well as the NSStackView documentation, and can't seem to find anything.

My problem is that I have two identical NSScrollView objects (each with an embedded NSTextView) which are loaded from nib files. When I add these views to my stack view, the one that is added first takes up 100% of the available space, and the second collapses completely down to the bottom with a height of 2 pixels while taking up all available horizontal space. In effect, this looks like the first view is the only one in the window. Here's what it currently looks like:

A screenshot of the problematic window

It's nearly impossible to see in this example because of the background color, but the scroll view ends a couple pixels above the bottom of the window. Here's a better view from the view hierarchy inspector, where I have this 2 pixel high view selected (click here to view larger):

The Xcode view hierarchy inspector

Here's the relevant setup code:

// Load the stack view
self.inputViewController = [[NSViewController alloc] initWithNibName:@"Document_TextInputView" bundle:nil];
self.textView = (NSTextView *)[[(NSScrollView *)self.inputViewController.view contentView] documentView];

self.outputViewController = [[NSViewController alloc] initWithNibName:@"Document_TextOutputView" bundle:nil];
self.outputView = (NSTextView *)[[(NSScrollView *)self.outputViewController.view contentView] documentView];

// Add all views into the stack view
[self.stackView addView:self.inputViewController.view inGravity:NSStackViewGravityTop];
[self.stackView addView:self.outputViewController.view inGravity:NSStackViewGravityBottom];
self.stackView.orientation = NSUserInterfaceLayoutOrientationVertical;

// Load the text into the window.
[self.textView setString:self.cachedText];
[self.outputView setString:@"=== PROGRAM OUTPUT ===\n"];
[self.codeActionSegmentedControl setEnabled:NO forSegment:1];

From what I understand, the intrinsic content size should prohibit the view from getting shrunk this small. I'm not too familiar with NSStackView, so any help would be appreciated.


Solution

  • Alright, I've found the solution to my own problem and I am posting it so everyone who searches for this and finds the question will have the answer.

    The issue is that NSScrollView does not have an intrinsic content size, which prohibits the NSStackView which knowing what height it ought to be, hence the second NSScrollView was being collapsed. The constraints created by default in Xcode give the NSScrollView's relation to other elements, but this information does not tell the stack view anything about what its height should be.

    The solution is to add a height constraint to the NSScrollView (programmatically or in Interface Builder) so that NSStackView can lay out the views properly. Then, it all just magically works.