在 cocoa 应用的不同视图控制器上启用或禁用菜单项?

Enable or disable menu items on different view controllers in cocoa app?

我有 3 个视图控制器,分别是 main1、main2 和 child。我添加了一个菜单项,单击它应该以模态方式打开子视图控制器。 每当用户在 main1 VC 中时,应启用菜单项。如果 main2 VC 中的用户,应禁用菜单。现在,我在菜单项和子项 VC 之间添加了模态转场。 我按照以下方法禁用,但它们不起作用。

方法一: 在 main2 VC 中,我添加了

 func validateUserInterfaceItem(_ anItem: NSValidatedUserInterfaceItem) -> Bool {
      return false
 }

 override func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
      return false
 }

方法二:

 override func viewDidLoad() {
      super.viewDidLoad()
      let mainMenu = NSApplication.shared().mainMenu!
      let appMenu = mainMenu.item(at: 0)!.submenu
      appMenu?.item(withTitle: someMenuTitle)?.isEnabled = false
 }

如果您使用模态转场,它将始终处于激活状态。 对于 enable/disable 依赖于呈现的视图控制器,我将向视图控制器添加一个操作以手动打开视图控制器作为模态。菜单项必须连接到具有第一响应者的操作 (openModalViewController)。

@IBAction func openModalViewController(_ sender: AnyObject) {

    let storyboard = NSStoryboard(name: "Main", bundle: nil)
    let viewController = storyboard.instantiateController(withIdentifier: "MyViewController") as! NSViewController
    presentAsModalWindow(viewController)
}

考虑必须至少有一个视图能够在 main1/main2 中获得第一响应者,菜单项将被激活。如果不是这种情况,您将不得不为相应的视图实施 acceptsFirstResponder

override var acceptsFirstResponder: Bool{
    return true
}

在这种情况下不需要实施 validateUserInterfaceItem,只有当您想要控制 activation/deactivation 依赖于其他状态时,如下例所示。

extension ViewController: NSMenuItemValidation {

    func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {

        if menuItem.action == #selector(delete(_:)) {
            return tableView.selectedRow < 0 ? false : true
        }

        return true
    }
}