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

断了今生、忘了曾经 提交于 2019-12-09 16:28:43

问题


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


回答1:


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.




回答2:


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.




回答3:


If you are converting a project from objective C to Swift, do not make my mistake. When writing your IBAction write like this:

 @IBAction func someAction(_ sender:AnyObject) {
     // this will work
 }

Do not omit the underscore before sender or the Interface Builder won't be able to connect to your action as in here:

 @IBAction func someAction(sender:AnyObject) {
     // this won't work and IB won't connect to this action
     // because sender will be part of the symbol name
 }


来源:https://stackoverflow.com/questions/28657058/why-cant-i-connect-my-menu-to-my-view-controller-ibaction

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