Search code examples
objective-cmacosnsviewcontrollernsstoryboard

Mac OSX Storyboard : communicate between NSViewController


I use storyboard in a OS X cocoa application project with a SplitView controller and 2 others view controller LeftViewController and RightViewController.

In the LeftViewController i have a tableView that display an array of name. The datasource and delegate of the tableview is the LeftViewController.

In the RightViewController i just have a centered label that display the select name. I want to display in the right view the name selected in the left view.

To configure the communication between the 2 views controllers i use the AppDelegate and i define 2 property for each controller in AppDelegate.h The 2 property are initialized in the viewDidLoad of view controller using the NSInvocation bellow :

@implementation RightViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    // Do any additional setup after loading the view.
    id delg = [[NSApplication sharedApplication] delegate];
    SEL sel1 = NSSelectorFromString(@"setRightViewController:");
    NSMethodSignature * mySignature1 = [delg methodSignatureForSelector:sel1];
    NSInvocation * myInvocation1 = [NSInvocation
                                    invocationWithMethodSignature:mySignature1];

    id me = self;

    [myInvocation1 setTarget:delg];
    [myInvocation1 setSelector:sel1];
    [myInvocation1 setArgument:&me atIndex:2];
    [myInvocation1 invoke];
}

I have the same in LeftViewController.

Then if i click on a name in the table view, i send a message to the delegate with the name in parameter and the delegate update the label of the RightViewController with the given name. It works fine but according to apple best practice it’s not good.

Is there another way to communicate between 2 view controller inside a storyboard ?

I've already read a lot of post but found nothing for OS X.

You can download the simple project here : http://we.tl/4rAl9HHIf1

Commnunicate between view controller


Solution

  • I managed to get what i want by adding the following code in AppDelegate.m :

    - (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
        // Insert code here to initialize your application
        //
        NSStoryboard *storyboard = [NSStoryboard storyboardWithName:@"Main"
                                                                bundle:[NSBundle mainBundle]];
    
        self.windowController = [storyboard instantiateControllerWithIdentifier:@"windowController"];
        self.window = self.windowController.window;
    
        self.splitViewController = (NSSplitViewController*)self.windowController.contentViewController;
        NSSplitViewItem *item0 = [self.splitViewController.splitViewItems objectAtIndex:0];
        NSSplitViewItem *item1 = [self.splitViewController.splitViewItems objectAtIndex:1];
        self.leftViewController = (OMNLeftViewController*)item0.viewController;
        self.rightViewController = (OMNRightViewController*)item1.viewController;
    
        [self.window makeKeyAndOrderFront:self];
        [self.windowController showWindow:nil];
    }
    

    We also need to edit the storyboard NSWindowController object as follow : Define a id for the NSWindowController

    Uncheck the checkbox 'Is initial controller' because we add it programmatically in AppDelegate.m.

    Uncheck the  checkbox 'Is initial controller

    Now the left and right view can communicate. Just define a property named rightView in OMNLeftViewController.h :

        self.leftViewController.rightView = self.rightViewController;