Невозможно обновить NSTouchBar программно - PullRequest
0 голосов
/ 04 марта 2019

В настоящее время я разрабатываю очень простое приложение для Mac OSX Live Scores для личного использования, в котором я показываю несколько ярлыков (баллов) на сенсорной панели.Чего я пытаюсь достичь, выполнив несколько шагов:

  1. Каждые 30 секунд извлекайте результаты футбольных матчей из стороннего API
  2. Анализируйте результаты и делайте их на ярлыки
  3. Обновите сенсорную панель новыми счетами

[Обратите внимание, что это приложение нигде не будет опубликовано и предназначено только для личного использования.Мне известно о том, что Apple строго советует против такого типа контента на сенсорной панели.]

Вот код, который я написал после базового учебника по сенсорной панели от RW (https://www.raywenderlich.com/883-how-to-use-nstouchbar-on-macos). Скелет моего кода выбран из учебника RW:

  1. В WindowController (точка входа в StoryBoard), переопределите makeTouchBar, например:
override func makeTouchBar() -> NSTouchBar? {
    guard let viewController = contentViewController as? ViewController else {
      return nil
    }
    return viewController.makeTouchBar()
  }
В ViewController, который также является делегатом сенсорной панели, реализуется makeTouchBar fn:
override func makeTouchBar() -> NSTouchBar? {
    let touchBar = NSTouchBar()
    touchBar.delegate = self
    touchBar.customizationIdentifier = .scoresBar
    touchBar.defaultItemIdentifiers = [.match1, .flexibleSpace, .match2, ... , .match10]

    return touchBar
  }
NSTouchBarDelegate в ViewController.scores - это место, где я храню свои полученные результаты (см. 5).Я возвращаю nil за просмотры, если результаты еще не получены:
extension ViewController: NSTouchBarDelegate {

    func touchBar(_ touchBar: NSTouchBar, makeItemForIdentifier identifier: NSTouchBarItem.Identifier) -> NSTouchBarItem? {

        if (<scores not fetched yet>) {
            return nil
        }
        // matchNum is the match number for which I am showing scores for
        let customViewItem = NSCustomTouchBarItem(identifier: identifier)
        customViewItem.view = NSTextField(labelWithString: self.scores[matchNum ?? 0])
        return customViewItem
    }
}
Чтобы периодически получать оценки, я запускаю таймер запланированного задания в viewDidLoad() моего viewcontroller, например:
_ = Timer.scheduledTimer(timeInterval: 30.0, target: self, selector: #selector(ViewController.fetchScores), userInfo: nil, repeats: true)
И, наконец, это моя функция fetchScores, которая также выполняет вызов для обновления сенсорной панели:
@objc func fetchScores() {
    let url = "<scores api end point>"
    Alamofire.request(url).responseJSON { response in
        if let json = response.result.value {
            // update self.scores here and fill it with latest scores

            if #available(OSX 10.12.2, *) {
                //self.touchBar = nil
                self.touchBar = self.makeTouchBar() // This is where I am calling makeTouchBar again to update Touch Bar content dynamically
            }

        }
    }

Насколько я понимаю из приведенного выше кода, когда я звонюmakeTouchBar in fetchScores и назначить его свойству touchBar моего viewcontroller, в идеале он должен вызвать функцию делегата touchBar(:makeItemForIdentifier) для обновления представления Touch Bar (поток SO в этом ).Но в моем случае touchBar(:makeItemForIdentifier) никогда не вызывается.Единственный раз, когда вызывается touchBar(:makeItemForIdentifier), это первый раз, когда makeTouchBar вызывается из моего WindowController (см. Пункт 1 выше).А поскольку результаты еще не получены, моя сенсорная панель остается пустой.

...