Search code examples
swiftxcode6autolayoutnssplitview

XCode6 NSSplitViewController Holding Priorities and canCollapse not working


I was hoping someone can help me out with this.

Whatever I do, either though IB or in code, I cannot make the new NSSplitViewController and its items to collapsable or hold their priorities.

It cannot be done from the interface builder although this video shows otherwise: https://www.youtube.com/watch?v=ZIIuPo4F6tQ

I can only make the splitview items to have minimum width in code but this is pretty much it. I tested both Swift and Objective-C implementations without luck.

This is what I have written in swift:

override func viewDidLoad() {
    super.viewDidLoad()

    // ---

    var left: NSSplitViewItem = self.splitViewItems[0] as NSSplitViewItem
    var right: NSSplitViewItem = self.splitViewItems[1] as NSSplitViewItem

    // ---

    // NOTE: these are not working properly in the interface builder for now

    self.view.addConstraint(NSLayoutConstraint(
        item: left.viewController.view,
        attribute: NSLayoutAttribute.Width,
        relatedBy: NSLayoutRelation.GreaterThanOrEqual,
        toItem: nil,
        attribute: NSLayoutAttribute.NotAnAttribute,
        multiplier: 0,
        constant: 200
    ))

    self.view.addConstraint(NSLayoutConstraint(
        item: right.viewController.view,
        attribute: NSLayoutAttribute.Width,
        relatedBy: NSLayoutRelation.GreaterThanOrEqual,
        toItem: nil,
        attribute: NSLayoutAttribute.NotAnAttribute,
        multiplier: 0,
        constant: 200
    ))

    // ---

    // NOTE: these are not working in the interface builder neither here but set anyway to demonstrate the problem

    left.canCollapse = true // has no effect
    right.canCollapse = true // has no effect

    // ---

    // NOTE: this is not working in the interface builder neither here but set anyway to demonstrate the problem

    right.holdingPriority = 1.0 // has no effect
}

None of this works at all. I even tried moving the call to super at the bottom of the function without much luck.

I was wondering if someone has identified a solution or perhaps I am doing something completely wrong?


Solution

    • Make the NSSplitViewController the delegate of the NSSplitView: e.g. in IB connect the delegate outlet of the NSSplitView to its controller. (Seems like this is not connected automatically in the IB-template as one would expect...)
    • Instead of coding you could use IB to change the holding priority of a NSSplitViewItem (so that for instance one is 249 and the other 250).
    • Here you can also check "Can Collapse" etc.
    • I also used IB to set min size constraints of the subviews.

    (One issue: after collapsing, i couldn't get the collapsed view back with the mouse; this might require implementing effective rect delegate methods. Update: effective rect doesn't apply when collapsed, so i think using NSSplitViewItem.collapsed in code seems to be the only way to un-collapse. This behavior is different to the 'classic' NSSplitView...)

    This basic setup worked as expected without specific coding or overriding. (OS X Storyboard App, Swift, Xcode 6.1)