NSSplitViewController/NSSplitViewItem support in XIBs

痞子三分冷 提交于 2021-01-27 14:24:19

问题


Is there support for NSSplitViewController/NSSplitViewItem for XIBs? I see only NSSplitView

Can I just drag&drop NSViewController and subclass it as NSSplitViewController? How do I add NSSplitViewItem that it mostly works out of the box?

I can easily see support for them in storyboards.


回答1:


The split view controller is not part of the object library for xib files. The easiest way to use split view controllers is to use storyboards.

If you are unwilling to use storyboards, your best option is to create a subclass of NSSplitViewController and select the checkbox to also create a xib file.

Add a split view to the split view controller xib file. Write code to load the xib file to set up the split view controller.

UPDATE

Look at the NSNib class reference for information on loading a xib file. The File's Owner of the xib file is your NSSplitViewController subclass. You may be able to use that information to set the split view controller. The worst case scenario is that you have to write code to load the split view from the xib file, set the split view controller's split view to the split view you loaded, and add the split view items to the split view controller. See the NSSplitViewController class reference for more information.




回答2:


Yes it's possible. But it needs some wiring.

First add a custom subclass of NSSplitViewItem and expose viewController property as IBOutlet. Compiler will throw a warning so don't forget to mark property as dynamic.

@interface MySplitViewItem : NSSplitViewItem
@property  IBOutlet NSViewController *viewController;
@end

@implementation MySplitViewItem
@dynamic viewController;
@end

In your XIB add 3 NSViewController objects. One of them change to custom class NSSplitViewController. It is important to note that one should NOT add NSSplitView. Wire NSViewControllers to it's views. Also add 2 objects and add custom class of MySplitViewItem which has exposed the viewController and wire it.

Last step. It is important to set property splitItems of NSSplitViewController before the views are loaded! Otherwise you are caught with NSAssert macro.

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    NSNib *nib = [[NSNib alloc] initWithNibNamed:@"Empty" bundle:nil];
    NSMutableArray *test = [NSMutableArray new];
    NSMutableArray *splitItems = [NSMutableArray new];
    NSSplitViewController *controller;
    [nib instantiateWithOwner:self topLevelObjects:&test];
    for (id object in test) {
        if ([object isKindOfClass:[NSSplitViewController class]]) {
            controller = object;
        }
        if ([object isKindOfClass:[NSSplitViewItem class]]) {
            [splitItems addObject:object];
        }
    }
    [controller setValue:splitItems forKey:@"splitViewItems"];
    [[self window] setContentViewController:controller];
}

Here is a proof that everything is wired correctly. Note that I did not touch delegate in XIB and it is wired. Magic, I know.

PS: XIB has to be set to prefer Coder + auto layout.

Why do I prefer XIB? Because we can create larger XIB which doesn't suffer from data isolation (Easily can do bindings across NSViewControllers).

I have also experimented to add splitViewItems in viewDidLoad or setView or awakeFromNib: in custom subclass of NSSplitViewController (with exposed NSSplitViewItem properties). If someone finds solution here it will be greatly appreciated.

Solution that requires code only:

- (NSSplitViewController *)profilesSVC
{
    if (!_profilesSVC) {
        NSSplitViewController *splitVC = [[NSSplitViewController alloc] init];
        ProfilesViewController *profilesVC = [[ProfilesViewController alloc] initWithNibName:@"Profiles" bundle:nil];
        NSSplitViewItem *leftItem = [NSSplitViewItem splitViewItemWithViewController:profilesVC];
        [splitVC addSplitViewItem:leftItem];
        ProfileViewController *profileVC = [[ProfileViewController alloc] initWithNibName:@"Profile" bundle:nil];
        NSSplitViewItem *rightItem = [NSSplitViewItem splitViewItemWithViewController:profileVC];
        [splitVC addSplitViewItem:rightItem];
        _profilesSVC = splitVC;
    }
    return _profilesSVC;
}


来源:https://stackoverflow.com/questions/54870957/nssplitviewcontroller-nssplitviewitem-support-in-xibs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!