为什么我不能将我的菜单连接到我的视图控制器 IBAction?

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

我有一个基于文档的应用程序。我刚刚在故事板中创建了菜单项,在我的视图控制器中创建了 IBActions。但是,我将动作连接到目标的常用方法不起作用

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

这是我在菜单项中按 Ctrl 键并从菜单单击鼠标到视图控制器时看到的内容。它没有显示我的 IBActions。

有什么想法吗?我的 2 美分猜测是它与基于文档的应用程序有关,但......不太确定

将菜单项连接到应用场景的First Responder。当您连接到应用程序场景的 First Responder 时,您的视图控制器的 IBAction 应该出现在 HUD 的可用操作列表中,而不是屏幕截图的 HUD 中显示的操作序列。

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

因为您的菜单项和视图控制器在情节提要中处于不同的场景。您可以将场景视为一个独立的对象图,当从情节提要中加载场景时,这些对象将被实例化。不同场景中的对象无法在故事板中连接在一起,因为它们不是同时加载的。

只是为了好玩,尝试在故事板的 Application Scene 中创建视图控制器的实例。为此,您可能需要将一个普通的旧 NSObject 实例拖到场景中,然后设置其类型。执行此操作后,您会发现可以将连接从菜单项拖动到该视图控制器,就像您期望的那样,但不能将连接拖动到不同类型的不同对象场景.

注意:一旦您尝试了足够多的内容并确信它有效,请记住删除您添加的视图控制器。没有视图的视图控制器就像没有嘎嘎叫的鸭子,视图控制器及其视图层次结构应该在它们自己的场景中。

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

不,与此无关。在非基于文档的应用程序中,您会遇到同样的问题。如果您的应用程序是基于 .xib 而不是使用故事板,您也会遇到同样的问题,因为您尝试连接的控制器将位于完全不同的 .xib 文件中。

正如 Mark 已经描述的那样,简单的解决方案是使用响应链。 First Responder 代理对象是每个场景的一部分,因此您始终可以与它建立联系。当您将菜单项连接到 First Responder 时,它的目标将是 nil,它告诉 NSMenu 遍历响应程序链,直到它找到响应菜单项的操作消息的对象。然后它将消息发送到该对象。

如果您要将项目从 objective C 转换为 Swift,请不要犯我的错误。在编写 IBAction 时,请这样写:

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

不要省略 sender 之前的下划线,否则 Interface Builder 将无法连接到您的操作,如下所示:

 @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
 }