【问题标题】:validateMenuItem not called for every menu itemvalidateMenuItem 不为每个菜单项调用
【发布时间】:2019-07-02 09:25:16
【问题描述】:

我的主菜单有几个菜单项(文件、编辑、视图、窗口等)。所有菜单项的操作都设置为FirstResponder 中的操作。

应用程序有一个窗口,该窗口的类型为MyWindow,继承自NSWindow(见下文)。

请注意,NSWindow 实现了NSMenuValidation,因此当MyWindow 声明符合NSMenuValidation 时,它被标记为错误。

我已经重写了函数validateMenuItem如下:

class MyWindow: NSWindow, NSMenuDelegate {

    ...

    override func validateMenuItem(_ item: NSMenuItem) -> Bool {
        Log.atDebug?.log("\(item.title)")
        ....
    }
}

当我运行应用程序时,FileWindow 菜单项调用了 validateMenuItem 函数,但EditView 项没有调用。

注意:Log 是日志框架 (SwifterLog) 的一个实例。

正确调用所有菜单项的操作。 (也适用于未调用validateMenuItem 的菜单项)

解决这个问题对我来说并不难(函数menuNeedsUpdate 被所有菜单调用并且可以用于此),但我想知道为什么会出现这种行为。

【问题讨论】:

  • 是文本字段、文本视图或其他对象验证编辑菜单项吗?
  • 我很震惊它完全有效。顶级子菜单项的验证/启用可能与 AppKit 内部工作中的某些巫术有关,并且这些顶级菜单项的正常验证正在短路。
  • @Willeke,它与 MyWindow 对象绑定,如使用 Firstresponder 的代码所示
  • @JamesBucanek:这在早期版本的 macOS 中运行良好(实际上是 OSX)
  • 如果您认为这是顶级菜单项的已记录功能不再正常工作,我建议您提交错误报告。但我的感觉是,这是私有框架代码的副作用,因此是一个移动的目标。错误报告反馈应该让您了解 Apple 对此事的看法——这比我的要重要得多。 ;)

标签: swift macos cocoa menu


【解决方案1】:

可以在这里找到答案: validateMenuItem or menuWillOpen not called for NSMenu

validateMenuItem: 属于NSMenuValidation 非正式协议; 要将其称为相关菜单项必须有一个目标

【讨论】:

    【解决方案2】:

    这不是答案,而是针对任何对解决方法感兴趣的人:

    @objc func menuNeedsUpdate(_ menu: NSMenu) {
    
        Log.atDebug?.log("\(menu.title)")
    
        ...    // do other stuff    
    
        menu.items.forEach( { $0.isEnabled = validateMenuItem($0) } )
    }
    

    您还必须将必须处理的每个菜单的委托设置为 MyWindow 对象(在此示例中)。在我的示例中,菜单项 View 的菜单必须将其委托设置为 MyWindow

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-10
      • 1970-01-01
      相关资源
      最近更新 更多