macoscocoaappkitnssplitviewnssplitviewcontroller

How to set custom NSSplitView with NSSplitViewController?


I'd like to use a custom NSSplitView with my NSSplitViewController.

The docs say:

To provide a custom split view, set this property at any time before you call super in the inherited viewDidLoad() method; that is, before the split view controller’s isViewLoaded property is true.

My NSSplitViewController subclass is called MainVC.

I tried setting my custom split view in -viewDidLoad before calling [super viewDidLoad]:

- (void)viewDidLoad {
    self.splitView = [MySplitView new];
    [super viewDidLoad];
    // Rest of viewDidLoad...
}

but it didn't work. I got the following error:

2017-09-02 10:35:43.527312-0700 Zee[6497:632581] ** * Assertion failure in -[MainVC setSplitView:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/AppKit/AppKit- 1561/Controllers/NSSplitViewController.m:220

2017-09-02 10:35:43.527558-0700 Zee[6497:632581] MainVC: The -splitView can only be assigned before the view is loaded

I also tried overriding loadView:

- (void)loadView {
    self.splitView = [MySplitView new];
    [super loadView];
}

But I get:

2017-09-02 10:39:39.377345-0700 Zee[6575:639146] ** * -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array

If I do the assignment after calling [super loadView], I get the same error as I did when I tried it in -viewDidLoad.

How do I use a custom NSSplitView in my NSSplitViewController subclass?


Solution

  • So the index out of bounds issue is related to your split view not having any content rather than something you're doing wrong with initialization. Leaving the initialization in the loadView should be fine. Simply make sure you have initialized your NSSplitViewController subclass with at least 2 NSSplitViewItems before presenting it. Here's an example:

    - (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
        MySplitViewController *vc = [MySplitViewController new];
        vc.splitViewItems = @[
            [NSSplitViewItem splitViewItemWithViewController:[MyViewController new]],
            [NSSplitViewItem splitViewItemWithViewController:[MyViewController new]]
        ];
        self.window.contentViewController = vc;
    }