相关控制器

时间:2017-02-26 15:49:26

标签: cocoa nsmenuitem nstoolbar nsresponder nstoolbaritem

我有一个NSToolbarItem,其中NSButton作为视图,主菜单中有NSMenuItem。两者都有相同的动作,发送给第一响应者,而不是特定目标。该方法最终在NSSplitViewController的子类中实现,位于窗口内容视图的视图层次结构中的某个位置。我想验证这两个项目,但让特定的拆分视图控制器负责验证,因为它依赖于该控制器本地的一些条件。

我在该分割视图控制器中覆盖了validateToolbarItem(_:)validateMenuItem(_:)。对于菜单项,这是按预期工作。调用该方法并进行验证。但是,永远不会调用validateToolbarItem(_:)

根据Apple’s documentation,NSToolbar不会将validateToolbarItem(_:)发送到基于视图的工具栏项。为了对此进行测试,我已将工具栏项替换为图像工具栏项,并在那里按预期工作。

基于此,我遇到了几个解决方案,但它们并不是我想要的。

  • 子类NSToolbarItem并覆盖validate()。但是,没有给出关于我最终如何让控制器validateToolbarItem(_:)致电的指导。

  • 子类NSToolbar并覆盖validateVisibleToolbarItems(),然后向第一个响应者发送消息。在这里,我遇到了问题,我无法向拆分视图控制器发送消息,因为它位于工具栏的响应程序链之外。

  • 如上所述,使用NSToolbar子类,但在响应者链中的控制器中实现validateToolbarItem(_:),例如NSWindowController。这可行,但后来我必须添加额外的代码来处理菜单项不需要的内容。

是否有一个优雅的解决方案,就像它对图像工具栏项和菜单项一样?

1 个答案:

答案 0 :(得分:4)

我在NSToolbarItem子类中为按钮编写了以下代码。使用此toolbarItem子类,您可以使用普通validateUserInterfaceItem()validateToolbarItem()来验证包含NSControl的工具栏项。

override func validate() {

    // validate content view
    if
        let control = self.view as? NSControl,
        let action = self.action,
        let validator = NSApp.target(forAction: action, to: self.target, from: self) as AnyObject?
    {
        switch validator {
        case let validator as NSUserInterfaceValidations:
            control.isEnabled = validator.validateUserInterfaceItem(self)
        default:
            control.isEnabled = validator.validateToolbarItem(self)
        }

    } else {
        super.validate()
    }
}