8

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

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

根据Apple 的文档,NSToolbar 不会发送validateToolbarItem(_:)到基于视图的工具栏项目。为了测试这一点,我用图像工具栏项目替换了工具栏项目,它可以按预期工作。

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

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

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

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

是否有一个优雅的解决方案可以像图像工具栏项和菜单项一样工作?

4

1 回答 1

15

我在按钮的 NSToolbarItem 子类中编写了以下代码。使用此工具栏项子类,您可以使用普通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()
    }
}
于 2017-02-27T05:42:16.450 回答