【问题标题】:Handle Menu Item Action in ViewController在 ViewController 中处理菜单项操作
【发布时间】:2018-01-09 08:41:05
【问题描述】:

我想在我的视图控制器中处理对菜单项“打开”的点击。

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

这是我第一个使用 cocoa 编写代码的应用程序,因此我对“响应者链”[2] 和“委托”还不是很熟悉,但似乎我必须对它们做点什么。

[1]Connect to ViewController from AppDelegate (Swift)
[2]Cocoa Storyboard Responder Chain

【问题讨论】:

标签: swift xcode macos cocoa


【解决方案1】:

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

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

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

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

【讨论】:

  • 非常感谢,我没有意识到我可以将函数命名为“openDocument”并且它会起作用。 (完整代码:@IBAction func openDocument(_ sender: Any) {}
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-18
  • 2012-04-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-16
相关资源
最近更新 更多