我想在视图控制器中单击“打开”菜单项。
似乎只能在我的AppDelegate中处理它。这里描述的问题[1]与我想做的事情非常相似,但我认为必须有一种更动态的方式,并且不要求AppDelegate知道在哪里转发它。如果我想根据当前视图更改操作该怎么办?
这是我用cocoa编写的第一个应用程序,所以我还不熟悉'Responder Chains'[2]和'Delegation',但似乎我必须对这些做些什么。
[1] Connect to ViewController from AppDelegate (Swift)
[2] Cocoa Storyboard Responder Chain
答案 0 :(得分:5)
如果我想根据当前视图更改操作该怎么办?
您确实需要了解响应者链以获取菜单命令的处理方式。简而言之,视图,视图控制器,窗口控制器,文档和应用程序本身都是NSResponder
的实例,它提供了处理按键和菜单命令等事件的机制。在任何特定时刻都有一个第一响应者,"这是第一个能够处理这类事件的对象。如果该对象没有处理相关事件,则事件将被传递给链中的下一个响应者,依此类推,直到它到达应用程序。
例如,当您键入字母" a"在基于Cocoa的文本编辑器中,按键被发送给第一响应者。如果文档窗口打开并处于活动状态,则第一个响应者可能会成为某个文本视图,这将插入" a"在插入点,并可能通知其代表文本已更改。另一方面,如果您选择同一窗口激活的File-> Close命令,该事件将从文本视图开始,可能无法处理它,因此它将被传递到superview,窗口,窗口控制器,最后到达文档,文档知道如何处理该命令。另一方面,如果命令是File-> Quit,则命令将在处理之前一直到应用程序。这被称为"响应者链"在Cocoa和Cocoa Touch编程中,这里的模式也称为"chain of responsibility."响应者链不仅用于处理事件,还用于菜单验证等。
上下文菜单命令的处理方式相同。唯一真正不同的是如何创建上下文菜单:当用户执行任何手势调出上下文菜单时(通常是控制点击或右键单击),上下文菜单是通过询问第一响应者(再次,当前"焦点和#34;)应该显示什么菜单。 NSView
有一个-menuForEvent:
方法,通常只返回视图的menu
属性的内容,因此您可以使用实例设置menu
属性NSMenu
,或者您可以覆盖-menuForEvent:
以便它构建菜单。当用户选择上下文菜单命令时,它将像任何其他菜单命令一样被处理,从第一响应者开始。这意味着第一响应者并不一定需要处理它提供的上下文菜单中的所有项目 - 可能有像" Copy"或"粘贴"由链上的其他对象处理。