Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set NSSplitView panels minimum & initial width using auto layout?

I am new to OS X cocoa development and am working on a Swift App using Storyboards for Yosemite.

In my application's main window, I have a NSSplitViewController. For each of the panels, left and right, I added a root custom view that will contain all the subviews.

Storyboard Layout

Using auto layout, I have pinned the custom view to the edges of the View in the Split View and have also defined a constraint for the width of the Custom View to be greater than or equals to a minimum number.

Autolayout Constraints

This all works fine. When the window opens, the window width is the sum of the minimum width constraints of the two panels. What I can't figure out is the next step.

How do I give Custom View another Width constraint so that when the window opens, it's initial width is higher than the minimum (lets say 300)? What I want is for the panel to be able to be as small as 200, but I want the initial size to be 300. I don't want the window to open at the smallest width allowed. Then the user will have to resize it every time and that would not be a good user experience.

To try and accomplish this, I added another Width constraint for 300 with a lower priority (Tried all different values 200, 500, 800, etc.) to the Custom View but none of them give me the desired result of the width value being 300 and the panel having a minimum width of 200.

Revised Autolayout constraints

There has to be a way to accomplish this, but I am just stumped on how. Please help!

Update

Here is the output from constraintsAffectingLayoutForOrientation for the NSSplitViewController's view:

<NSLayoutConstraint:0x6000000923e0 H:|-(0)-[NSView:0x600000124c40]   (Names: '|':NSView:0x600000124ba0 )>, 
<NSLayoutConstraint:0x6000000924d0 H:[NSView:0x600000124c40]-(0)-|   (Names: '|':NSView:0x600000124ba0 )>, 
<NSLayoutConstraint:0x600000092070 H:[NSView:0x600000124c40(>=200)]>, 
<NSLayoutConstraint:0x600000092660 _NSSplitViewItemViewWrapper:0x6000001416b0.width == NSView:0x600000124ba0.width>, 
<NSLayoutConstraint:0x600000093a10 H:|-(0)-[_NSSplitViewItemViewWrapper:0x6000001416b0](LTR)   (Names: '|':NSSplitView:0x608000123b60 )>, 
<NSLayoutConstraint:0x600000093b50 H:[_NSSplitViewItemViewWrapper:0x6000001416b0]-(1)-[_NSSplitViewItemViewWrapper:0x6000001429f0](LTR)>, 
<NSAutoresizingMaskLayoutConstraint:0x600000093d80 h=-&- v=-&- H:[NSSplitView:0x608000123b60]-(0)-|   (Names: '|':NSView:0x6000001242e0 )>, 
<NSAutoresizingMaskLayoutConstraint:0x600000093b00 h=-&- v=-&- H:|-(0)-[NSSplitView:0x608000123b60]   (Names: '|':NSView:0x6000001242e0 )>, 
<NSAutoresizingMaskLayoutConstraint:0x600000094050 h=-&- v=-&- H:|-(0)-[NSView:0x6000001242e0]   (Names: '|':NSThemeFrame:0x100940be0'Main Window' )>, 
<NSLayoutConstraint:0x600000093c40 H:[_NSSplitViewItemViewWrapper:0x6000001429f0]-(0)-|(LTR)   (Names: '|':NSSplitView:0x608000123b60 )>, 
<NSLayoutConstraint:0x600000092890 H:[NSView:0x600000124f60]-(0)-|   (Names: '|':NSView:0x600000124ec0 )>, 
<NSLayoutConstraint:0x6000000926b0 H:[NSView:0x600000124f60(>=400)]>, 
<NSLayoutConstraint:0x608000099d20 _NSSplitViewItemViewWrapper:0x6000001429f0.width == NSView:0x600000124ec0.width>, 
<NSLayoutConstraint:0x600000092840 H:|-(0)-[NSView:0x600000124f60]   (Names: '|':NSView:0x600000124ec0 )>]

Because of the large number of constraints to sort through, I decided to make a brand new test project and see if this happens out of the box or was it some setting that I changed in my application. In the test project I just deleted the view controller, added a Split View Controller to the window and just added two simple text views to each panel. Then running the project, the left hand side panel was collapsed. So I added a minimum width constraint to each text view and then the same thing happened in the test project. No matter what I set it to in the storyboard, the window size is the addition of the minimum widths. Maybe the only way to get past this is to set the window/split view size in code.

like image 431
Gaurav Avatar asked May 19 '15 02:05

Gaurav


1 Answers

You should not have to add additional constraints to force this. The window will, by default, have the size it's configured with in the storyboard. If it's getting smaller, that suggests there are constraints that are forcing it smaller.

A window will maintain its size at priority 500 (NSLayoutPriorityWindowSizeStayPut). Constraints of higher priority can push or pull it to a different size. Lower-priority constraints will be overridden by the window's current size.

So, you should look for constraints with priority higher than 500 that try to pull it narrower. For example, content hugging priorities of controls. Another possibility is the holding priority of the split view items. If those are higher than 500 and the initial size of the views as loaded from the storyboard is the minimum, then I expect the split view will prefer to keep them at those sizes more strongly than the window will prefer to keep its size.

A possibly useful diagnostic technique is to log [someView constraintsAffectingLayoutForOrientation:NSLayoutConstraintOrientationHorizontal]. You might do that for the window's contentView or the split view.

like image 173
Ken Thomases Avatar answered Nov 20 '22 15:11

Ken Thomases