在AppKit上,菜单项和工具栏项分别具有validateMenuItem(_ :)和validateToolbarItem(_ :).但是,通过新的触摸条项目,没有这种方便的方法来在适当的时刻验证适当的项目. 我现在每次更改相关值并在
我现在每次更改相关值并在didSet中调用验证方法时验证触摸条项(请参阅下面的示例代码).但我觉得这不是一个好方法,因为相关的值必须知道有一个触摸栏项目取决于它.
var foo: Foo? { didSet { if #available(macOS 10.12.1, *), NSClassFromString("NSTouchBar") != nil { self.validateTouchBarItem(identifier: .foo) } } } @available(macOS 10.12.1, *) func validateTouchBarItem(identifier: NSTouchBarItemIdentifier) { guard let item = self.touchBar?.item(forIdentifier: identifier), let button = item.view as? NSButton else { return } switch identifier { case NSTouchBarItemIdentifier.foo: button.isEnabled = (self.foo != nil) default: break } }
我使用的另一种方式是Cocoa绑定和KVO,但是,它并不总是很好用.
所以,我很好奇是否有任何推荐或事实标准的方式来验证触摸条项目,特别是包含NSButton和NSSegmentedControl.我不仅要改变物品的可用性,还要根据情况改变它们的图像或颜色.你们如何验证触控条项目?
我自己改进了触摸条验证系统并制作了以下协议和扩展.@available(macOS 10.12.1, *) protocol TouchBarItemValidations: class { func validateTouchBarItem(_ item: NSTouchBarItem) -> Bool } @available(macOS 10.12.1, *) extension NSTouchBarProvider { func validateTouchBarItems() { guard NSClassFromString("NSTouchBar") != nil else { return } // run-time check guard let touchBar = self.touchBar else { return } // validate currently visible touch bar items for identifier in touchBar.itemIdentifiers { guard let item = touchBar.item(forIdentifier: identifier) as? NSCustomTouchBarItem else { continue } item.validate() } } } @available(macOS 10.12.1, *) extension NSCustomTouchBarItem: NSValidatedUserInterfaceItem { func validate() { // validate content control if let control = self.control, let action = control.action, let validator = NSApp.target(forAction: action, to: control.target, from: self) { if let validator = validator as? TouchBarItemValidations { control.isEnabled = validator.validateTouchBarItem(self) } else if let validator = validator as? NSUserInterfaceValidations { control.isEnabled = (validator as AnyObject).validateUserInterfaceItem(self) } } } // MARK: Validated User Interface Item Protocol public var action: Selector? { return self.control?.action } public var tag: Int { return self.control?.tag ?? 0 } // MARK: Private Methods private var control: NSControl? { return self.view as? NSControl } } @available(macOS 10.12.1, *) extension AppDelegate { func applicationDidUpdate(_ notification: Notification) { // validate touch bar items if #available(macOS 10.12.1, *) { if let window = NSApp.mainWindow { for responder in sequence(first: window.firstResponder, next: { $0.nextResponder }) { responder.validateTouchBarItems() } } } } }
你应该修改AppDelegate的applicationDidUpdate(:_),如果你已经有一个,但除此之外,没有任何复杂的添加.您现在可以使用validateTouchBarItem(_ :)或普通的validateUserInterfaceItem(_ :)来验证您自己的触控条项目!
我认为这至少可以满足我的要求.