在视图控制器中处理菜单项操作



我想在我的视图控制器中处理菜单项"打开"的单击。

似乎只能在我的应用程序委托中处理它。这里描述的问题 [1] 与我想做的事情非常相似,但我认为必须有一种更动态的方法,并且不需要 AppDelegate 知道将其准确转发到哪里。如果我想根据当前视图更改操作,该怎么办?

这是我第一个用可可编码的应用程序,所以我对"响应链"[2]和"委派"还不是很熟悉,但似乎我必须对这些做点什么。

[1] 从 AppDelegate 连接到 ViewController (Swift)
[2] Cocoa Storyboard Responder Chain

如果我想根据当前视图更改操作怎么办?

您确实需要了解响应器链才能了解如何处理菜单命令。简而言之,视图、视图控制器、窗口控制器、文档和应用程序本身都是NSResponder的实例,它提供了处理按键和菜单命令等事件的机制。在任何给定的时刻,都有一个"第一响应者",这是第一个有机会处理此类事件的对象。如果该对象不处理相关事件,则该事件将传递给链中的下一个响应者,依此类推,直到它到达应用程序。

例如,当您在基于 Cocoa 的文本编辑器中键入字母"a"时,该键将发送给第一响应者。如果有一个文档窗口打开并处于活动状态,则第一个响应者可能是某个文本视图,它将在插入点插入"a",并可能通知其委托文本已更改。另一方面,如果选择在同一窗口处于活动状态的情况下选择 File->Close 命令,则该事件将从文本视图开始,文本视图可能不会处理它,因此它将向上传递到超级视图、窗口和窗口控制器,最后到达知道如何处理该命令的文档。另一方面,如果命令是 File->Quit,则该命令将在处理之前一直到应用程序。这在Cocoa和Cocoa Touch编程中被称为"响应者链",但这里的模式也被称为"责任链"。响应程序链不仅用于处理事件,还用于菜单验证等操作。

上下文菜单命令的处理方式相同。唯一真正不同的是上下文菜单的创建方式:当用户执行任何手势时,通常会显示上下文菜单(通常是控制单击或右键单击),通过询问第一个响应者(再次,当前"焦点"的东西)来动态构建上下文菜单应该显示什么菜单。NSView有一个通常只返回视图的menu属性内容的-menuForEvent:方法,因此您可以使用NSMenu的实例设置menu属性,也可以重写-menuForEvent:以便它生成菜单。当用户选择上下文菜单命令时,它将像任何其他菜单命令一样进行处理,从第一个响应者开始。这意味着第一响应者不一定需要处理它提供的上下文菜单中的所有项目——可能有像"复制"或"粘贴"这样的项目由链上的其他对象处理。

最新更新