【问题标题】:Update NSTouchBar on the fly to add/remove items programmatically即时更新 NSTouchBar 以编程方式添加/删除项目
【发布时间】:2017-04-07 04:39:04
【问题描述】:

我目前正在为我的 macOS 应用程序实现 NSTouchBar api。

此时,我唯一拥有的触摸栏将主视图控制器作为其委托,我可以向其添加项目。问题是,我需要其中一些项目仅在满足特定条件时才出现(在表格中选择了一行)。

考虑一下我有一个布尔值来指示按钮是否应该可见。如果我的布尔值发生变化,如何即时更新 NSTouchBar 以显示/隐藏此按钮? (我不需要观察这个布尔值,我可以简单地在我已经实现的另一个方法中调用更新)

我现在所做的如下:在touchBar(:makeItemForIdentifier) 中,我有一个用于所有标识符的开关,在正确的case 下,我要么用按钮返回NSCustomTouchBarItem,要么返回nil,如果我的布尔值是false

我尝试在选择表格的一行后再次调用makeTouchBar,但它不会更新按钮的可见性,就好像没有再次调用touchBar(:makeItemForIdentifier)

谢谢!

【问题讨论】:

  • 你试过设置触摸项的isVisible属性吗?
  • 该属性是只读的。

标签: swift macos swift2 nstouchbar


【解决方案1】:

四个想法:

  1. 尝试将触摸栏的defaultItemIdentifiers 更改为应显示的项目标识符集。请注意,如果用户自定义了触摸栏,这将是有问题的,但我认为按需交换项目和自定义触摸栏并不能很好地结合在一起。这还有一个好处是您不需要在 touchBar(:makeItemForIdentifier:) 中返回 nil。
  2. 调用makeTouchBar() 将创建一个新的NSTouchBar 实例,但不会更改touchBar 属性。尝试类似

    viewController.touchBar = viewController.makeTouchBar()
    

    viewController.touchBar = nil
    
    1. NSTableRowView 上设置touchBar 属性,该属性应在选中时显示额外项目,并确保在defaultItemIdentifiers 中包含otherItemsProxy。由于触摸栏的内容由响应者链中的所有元素组成,这可能包括表格行的touchBar 属性(前提是它可以成为第一响应者)。

    2. 确定在未选择行时这些项目应该隐藏吗?考虑禁用它们(例如,将它们包含的按钮的enabled 属性设置为false)。

【讨论】:

  • 感谢您的详细解答。我将尝试各种提议并报告回来。我已经可以说 4. 对我来说不是最佳选择,因为条形图的几何限制(即允许的可见元素数量有限)。我可能想在这方面尽量减少空间浪费。
  • 您还可以做的是始终将项目放在栏中,但可见性优先级非常低。当项目变得重要时,只需提高其可见性优先级即可。
  • 报告回来高兴地说 2. 成功了!当项目应隐藏时,结合在 touchBar(:makeItemForIdentifier:) 中返回 nil。其他解决方案也可能有效。
  • 我看到第二种解决方案留下了一个问题(返回 nil 用于隐藏元素)。如果用户在这些项目应该被禁用的情况下自定义了触摸栏,他们将不会在自定义界面中看到按钮的预览。最后,我想我会使用 4.(禁用按钮),它也很好用。
【解决方案2】:

只需使视图控制器中的触摸栏无效:

self.touchbar = nil

然后将自动调用委托方法makeTouchBar()。使用您的标志,您可以轻松选择要显示的图标。

编辑:这个解决方案已经过测试并且工作正常。

【讨论】:

  • 感谢您的输入,但 MrMage 在他的回答中已经说过了(第 2 点)
  • 编辑了我的答案以反映它已经过测试的事实。第一个答案是想法。
  • 谢谢!除非触摸栏是可自定义的,否则这将正常工作。如果栏是可定制的,我认为没有一种优雅的方法可以暂时从栏中隐藏项目。如果您未在 touchBar(:makeItemForIdentifier:) 中返回项目,则自定义菜单中的预览将失败(我们可以在此方法中使用一个参数来了解我们是否应该返回实际栏或自定义菜单预览的项目)或者您如果您不将它们包含在makeTouchBar() 中,则它们根本不会出现在自定义菜单中。这是一个 macOS 问题。
  • 您能否先说明一下您是如何实现 Touch Bar 的?对我来说,这个解决方案不起作用,我必须打电话给 self.view.window?.windowController?.touchBar = nil 才能让它起作用。
  • 在每个 ViewController 中纯粹用代码制作。 override func makeTouchBar() -> NSTouchBar? { let touchBar = NSTouchBar() touchBar.delegate = self touchBar.defaultItemIdentifiers = [NSTouchBarItem.Identifier.fixedSpaceLarge, .touchBarAddButtonIdentifier, .touchBarRemoveButtonIdentifier] return touchBar }
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-03-06
  • 1970-01-01
  • 2020-03-25
  • 2012-11-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多