首页 > 解决方案 > 无法以编程方式更新 NSTouchBar

问题描述

我目前正在开发一个非常简单的 Live Scores MAC OSX 应用程序供个人使用,我在触摸栏上显示一堆标签(分数)。我想通过几个步骤实现:

  1. 每 30 秒从第 3 方 API 获取实时足球比分
  2. 解析分数并将其制成标签
  3. 使用新分数更新触控栏

[请注意,此应用不会在任何地方发布,仅供个人使用。我知道 Apple 严格建议不要在 Touch Bar 中使用此类内容。]

这是我在 RW ( https://www.raywenderlich.com/883-how-to-use-nstouchbar-on-macos )的基本 Touch Bar 教程之后编写的代码。我的代码骨架是从 RW 教程中挑选出来的:

  1. WindowController(StoryBoard 入口点)中,makeTouchBar像这样覆盖:
override func makeTouchBar() -> NSTouchBar? {
    guard let viewController = contentViewController as? ViewController else {
      return nil
    }
    return viewController.makeTouchBar()
  }
  1. ViewController也是 Touch Bar Delegate 中,实现makeTouchBarfn:
override func makeTouchBar() -> NSTouchBar? {
    let touchBar = NSTouchBar()
    touchBar.delegate = self
    touchBar.customizationIdentifier = .scoresBar
    touchBar.defaultItemIdentifiers = [.match1, .flexibleSpace, .match2, ... , .match10]

    return touchBar
  }
  1. NSTouchBarDelegateViewController. 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
    }
}
  1. 为了定期获取分数,我在viewDidLoad()我的视图控制器中运行计划任务计时器,如下所示:
_ = Timer.scheduledTimer(timeInterval: 30.0, target: self, selector: #selector(ViewController.fetchScores), userInfo: nil, repeats: true)
  1. 最后,这是我的fetchScores函数,它也调用更新 Touch Bar:
@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
            }

        }
    }

我对上面代码的理解是,一旦我调用makeTouchBarinfetchScores并将其分配给我的 viewcontroller 的touchBar属性,理想情况下它应该调用touchBar(:makeItemForIdentifier)委托函数来更新 Touch Bar 视图(此线程上的 SO 线程)。但就我而言,touchBar(:makeItemForIdentifier)从未调用过。唯一touchBar(:makeItemForIdentifier)被调用的时间是第一次,当makeTouchBar从我的 WindowController 调用时(参见上面的第 1 点)。由于尚未检索到分数,我的触摸栏仍然是空的。

标签: swiftmacosswift4macos-mojavenstouchbar

解决方案


推荐阅读