Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I connect my menu to my view controller IBAction?

I have a document based application. I have just created menu items in the storyboard and IBActions in my view controller. However the usual way I connect an action to a target doesn't work

-(IBAction) markAsHidden:(id)sender;
-(IBAction) markAsVisible:(id)sender;
-(IBAction) toggleHidden:(id)sender;

Here is what I see when from my menu item I press Ctrl and mouse click from menu to View Controller. It does not show my IBActions.

Any idea ? My 2 cents guess is that it has to do with the app being document based but... not really sure

connection menu

like image 752
Thomas Avatar asked Feb 22 '15 11:02

Thomas


2 Answers

Why can't I connect my menu to my view controller IBAction?

Because your menu items and view controller are in different scenes in the storyboard. You can think of a scene as an independent graph of objects that are instantiated when the scene is loaded from the storyboard. Objects in different scenes can't be connected together in the storyboard because they're not loaded at the same time.

Just for fun, try creating an instance of your view controller in the Application Scene in your storyboard. To do that, you'll probably need to drag a plain old NSObject instance into the scene and then set its type. Once you do that, you'll find that you can drag a connection from a menu item to that view controller just as you'd expect, but you can't drag a connection to a different object of the very same type in a different scene.

Note: Once you've played around enough to convince yourself that it works, remember to delete the view controller that you added. A view controller without a view is like a duck without a quack, and a view controller and its view hierarchy should be in their own scene.

My 2 cents guess is that it has to do with the app being document based

No, it doesn't have anything to do with that. You'd have the same problem in an app that's not document-based. You'd also have the same problem if your app were .xib-based instead of using storyboards, since the controller you'd be trying to connect to would be in a completely different .xib file.

The easy solution, as Mark already described, is to use the responder chain. The First Responder proxy object is part of every scene, so you can always make connections to it. When you connect a menu item to First Responder its target will be nil, which tells NSMenu to walk the responder chain until it finds an object that responds to the menu item's action message. It then sends the message to that object.

like image 84
Caleb Avatar answered Nov 17 '22 21:11

Caleb


Connect the menu items to the application scene's First Responder. When you connect to the application scene's First Responder, your view controller's IBActions should appear in the HUD's list of available actions instead of the action segues shown in your screenshot's HUD.

like image 19
Swift Dev Journal Avatar answered Nov 17 '22 23:11

Swift Dev Journal