7

I'm having a heck of a time setting up a simple split view. The first split view is collapsed. I need to set a minimum width for it. Everything I see online (scarce for NSSplitViewController/NSSplitView) is for Objective-C, puts everything in the app delegate, and uses XIBs.

Here's the scenario: Window Controller with a segue to a SplitView Controller, which has two split views (2 view controllers).

Which object needs to have the NSSplitViewDelegate?

EDIT: Adding code snippet: For example, I have this:

import Cocoa

class ViewController: NSSplitViewController, NSSplitViewDelegate {


    @IBOutlet weak var pdlSplitView: NSSplitView!

    override func viewDidLoad() {
        super.viewDidLoad()

        }
    override func splitView(splitView: NSSplitView, constrainMinCoordinate proposedMinimumPosition: CGFloat, ofSubviewAt dividerIndex: Int) -> CGFloat {
        return proposedMinimumPosition + 200
    }

}

Is there more that I'm missing?

Thanks

UPDATE

Based on comments below, I've made a change, but now I get a sigAbort on the class definition for the AppDelegate. Full code

ViewController:

import Cocoa

class ViewController: NSSplitViewController, NSSplitViewDelegate {


    @IBOutlet weak var pdlSplitView: NSSplitView!

    let publicDataListings : PDL = PDL()


    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        self.pdlSplitView.delegate = self

    }

    override func splitView(splitView: NSSplitView, constrainMinCoordinate proposedMinimumPosition: CGFloat, ofSubviewAt dividerIndex: Int) -> CGFloat {
    return proposedMinimumPosition + 200
    }

}

SidebarViewController:

import Cocoa

class SidebarViewController: NSViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do view setup here.
    }


}

DatasetViewController:

import Cocoa

class DatasetViewController: NSViewController, NSSplitViewDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do view setup here.
    }

}

Update I took away my custom NSSplitViewController class and created two NSSplitView classes, one with the constraint method. Now, I see both subviews, but they're far smaller than they should be:

enter image description here

Is there anyone at all that has done this with Swift and Storyboards?

Mike Pulsifer
  • 279
  • 2
  • 11
  • 1
    Are you using auto layout? What is the earlier version of the OS on which you want your app to run? If you're targeting 10.8 or later and using auto layout, the split view will honor the constraints of its subviews. So, the minimum width could be be implicit because something within the subview has an intrinsic width and resists compression and has leading and trailing constraints to subview. Or you could create an explicit width constraint on the subview that it be greater than or equal to some constant. – Ken Thomases Jan 17 '15 at 20:55
  • I'm OK with targeting 10.10+. I'm trying to do this in Swift. I've tried applying the constraints, but they don't stick. I know it's a mobile world now, but heck, I'd pay for just a SplitView Hello World in Swift right about now. Then I'd be off to the races. – Mike Pulsifer Jan 17 '15 at 21:14
  • If you implement certain split view delegate methods, then the split view won't use auto layout. See the AppKit Release Notes for 10.8 for the specifics. Also, I'm not sure if the split view delegate methods are compatible with `NSSplitViewController`. If removing that delegate method doesn't help, show the constraints you tried to set up and how you did it. – Ken Thomases Jan 17 '15 at 21:22
  • Removing NSSplitViewController creates an error at the delegate method. – Mike Pulsifer Jan 18 '15 at 21:40
  • I didn't suggest removing that. I was suggesting that you use auto layout and not the `NSSplitViewDelegate` methods which attempt to constrain view sizes. – Ken Thomases Jan 18 '15 at 21:55
  • In regards to your recent edit, what constraints are there within the subviews? – Ken Thomases Jan 19 '15 at 00:27
  • I updated the [https://github.com/USDepartmentofLabor/Public-Data-Listing-Consolidator](GitHub repo). Basically, I moved the same constraint I was trying to use in the NSSPlitViewController to the NSSplitView. – Mike Pulsifer Jan 20 '15 at 13:07

3 Answers3

22

No coding is required to set a minimum width in a storyboard with auto layout for a NSSplitViewController/NSSplitView.

Select the CustomView that you require a minimum width for (e.g. 200), and add a width constraint set to the required value which will add a "Equal" constraint (e.g. Custom View.Width equals 200).

Next locate that new constraint and change the constraint relation to "Greater Than or Equal" (e.g. so you now have width ≥ 200).

You now have a minimum width in an NSSplitView. You can then use the Priority field to resolve any conflicts with any other auto layout constraints.

Mythlandia
  • 576
  • 1
  • 5
  • 15
  • 7
    Thanks. This was a complete mystery, until you know it is there! :-) It might help your answer to include a screenshot. – RichS Apr 25 '16 at 09:56
  • Thanks, I was struggling with this. The >= and <= settings for constraints are hard to find if you don't know they exist. – Joe Wilcoxson Jun 03 '16 at 19:16
  • 2
    So I selected my view and tried setting a new width constraint. Constraint options are disabled for me. Am I missing something? – AnaghSharma Jun 27 '18 at 06:13
  • 1
    @AnaghSharma You cannot set constraints for a contentView, (the root view of a scene), just its contents, so you'd have to create a custom view, pin it to the top/leading edge, and give it an 'or greater' width constant to use this solution. (usually, you have content you can constrain) – green_knight Jul 15 '20 at 14:51
1

These values are not exposed in the storyboard, which is a great shame, but NSSplitViewItem has minimumThickness and maximumThickness properties which you can use. (This overrides the holding priority, so if you set minimumThickness for one splitViewItem, the other one(s) will now shrink into nothing if you make the window small enough.)

There is also automaticMaximumThickness (I cannot work out how this interacts with the other values) and preferredThicknessFraction which had no effect when I played with it under 10.13.

green_knight
  • 1,319
  • 14
  • 26
-2
  1. Set NSSplitViewController as delegate of NSSplitView (the split view you want to constrain). In your case it should be - in xib hook the delegate outlet of the NSSplitView to file owner (I guess the file owner is NSSplitViewController subclass)
  2. Implement

    - (CGFloat)splitView:(NSSplitView *)splitView constrainMinCoordinate:(CGFloat)proposedMin ofSubviewAt:(NSInteger)dividerIndex { ... }
    

in NSSplitViewController

https://developer.apple.com/library/mac/documentation/Cocoa/Reference/NSSplitViewDelegate_Protocol/index.html#//apple_ref/occ/intfm/NSSplitViewDelegate/splitView:constrainMinCoordinate:ofSubviewAt:

Sinisa Drpa
  • 887
  • 1
  • 5
  • 16
  • in the XIB? Shouldn't we be using storyboards? That's where everything is right now. Please see my edit above for the code I currently have. – Mike Pulsifer Jan 17 '15 at 20:55
  • The code above you posted is correct, just set ViewController to be delegate of the split view you want to constrain. in ViewController : override func viewDidLoad() { super.viewDidLoad() splitView.delegate = self; } – Sinisa Drpa Jan 17 '15 at 22:04
  • override func viewDidLoad() { super.viewDidLoad(); pdlSplitView.delegate = self; } – Sinisa Drpa Jan 17 '15 at 22:13
  • Here is working example (it's in ObjC) but it's 95% the same code as swift , you'll get the idea: http://tagtaxa.com/download/SplitExample.zip – Sinisa Drpa Jan 17 '15 at 22:21
  • I tried what you suggested. I get an error now. I've updated the post with additional code and a link to the full code. – Mike Pulsifer Jan 18 '15 at 21:41
  • Just tried your code, never seen that before, maybe this might help: http://stackoverflow.com/questions/26982714/nssplitviewcontroller-in-osx-10-10-using-xcode-6 – Sinisa Drpa Jan 18 '15 at 22:05
  • Updated above. Things just got weird. – Mike Pulsifer Jan 18 '15 at 22:21
  • FYI, this no longer works as of 10.11 when using auto-layout. – Joe Wilcoxson Jun 03 '16 at 19:18