2016-11-25 4 views
4

В AppKit элементы меню и элементы панели инструментов имеют validateMenuItem(_:) и validateToolbarItem(_:) соответственно. Однако с помощью новых элементов сенсорной панели нет такого метода удобства для проверки соответствующих элементов в нужный момент.Лучший практический способ проверки элементов NSTouchBar

Теперь я проверяю элементы штриховки каждый раз, когда изменяю связанные значения и вызывается метод проверки в 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 
    } 
} 

Другим способом, который я использую, является связывание какао и KVO, однако оно не всегда хорошо работает.

Итак, мне любопытно, есть ли какой-либо рекомендуемый или дефакто-стандартный способ проверки элементов сенсорной панели, особенно содержащий NSButton и NSSegmentedControl. Я хочу изменить не только доступность предметов, но иногда и изображения или цвета их в зависимости от ситуации. Как вы, ребята, проверяете элементы сенсорной панели?

ответ

6

Я улучшил свою систему проверки сенсорного планшета самостоятельно и сделал следующий протокол и расширения.

@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(_:), чтобы проверить свои позиции на сенсорной панели!

Я полагаю, что это работает, по крайней мере, для моих требований.

+0

После этого ответа я улучшил свое приложение. См. Https://github.com/coteitor/CotEditor/blob/develop/CotEditor/Sources/NSTouchBar%2BValidation.swift для получения последнего кода. – 1024jp

Смежные вопросы