2017-02-26 82 views
2

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

我在该分屏控制器中覆盖了validateToolbarItem(_:)validateMenuItem(_:)。对于菜单项,这是按预期工作的。该方法被调用并且验证发生。然而,从未调用过validateToolbarItem(_:)

根据Apple’s documentation,NSToolbar不会将validateToolbarItem(_:)发送到基于视图的工具栏项目。为了测试这个,我用工具栏项目替换了工具栏项目,并且它按预期工作。

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

  • 子类NSToolbarItem并覆盖validate()。然而,我没有给出任何指导,我最终得到的控制器的validateToolbarItem(_:)来电。

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

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

是否有一个优雅的解决方案,它的工作原理与图像工具栏项目和菜单项一样?

回答

2

我在按钮的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() 
    } 
} 
+0

神奇,只是我寻找的优雅的解决方案。非常感谢! – Eitot

+0

美丽!感谢分享这个。你介意解释两件事:1)为什么这甚至是需要的 - 为什么可可不这样做?和b)我多久应该期待这个被称为?在我快速实现你的代码时,它似乎被称为非常不可预测的,而且经常。 –

+0

@ jeff-h 1)NSToolbarItem的内部视图可以不仅仅是一个NSControl。所以Cocoa不知道它是什么,因此如何验证它。 2)这是一个活动组合和一个计时器。您可以在引用中看到验证时间的详细信息:https://developer.apple.com/reference/appkit/nstoolbar/1516947-validatevisibleitems – 1024jp