beeb beeb - 17 days ago 15
Swift Question

Update NSTouchBar on the fly to add/remove items programmatically

I'm currently implementing the NSTouchBar api to my macOS application.

At this moment, the only touch bar I have has the main View Controller as its delegate and I can add items to it fine. The catch is, I need some of those items to appear only when a certain condition is met (a row is selected in a table).

Consider I have a boolean that indicates whether or not the button should be visible. How do I update the NSTouchBar on the fly to show/hide this button in case my boolean changes? (I don't need to observe this boolean, I could simply make the call to update in another method I already implemented)

What I did for now is the following: in

touchBar(:makeItemForIdentifier)
, I have a switch for all identifiers, and under the proper
case
, I either return the
NSCustomTouchBarItem
with the button, or
nil
if my boolean is
false
.

I tried calling
makeTouchBar
again after a row of the table is selected but it doesn't update the buttons' visibility, as if
touchBar(:makeItemForIdentifier)
is not called again.

Thanks!

Answer

Four ideas:

  1. Try changing your touch bar's defaultItemIdentifiers to the set of item identifiers that should be shown. Note that this would be problematic if the user has customized the touch bar, but I think swapping items on-demand and customizing the touch bar doesn't go well together anyway. This also has the advantage that you don't need to return nil in touchBar(:makeItemForIdentifier:).
  2. Calling makeTouchBar() will create a new NSTouchBar instance, but not change the touchBar property. Try something like

    viewController.touchBar = viewController.makeTouchBar()
    

    or

    viewController.touchBar = nil
    
    1. Set the touchBar property on the NSTableRowView that should show extra items when selected, and make sure to include the otherItemsProxy in your defaultItemIdentifiers. As the contents of the touch bar are comprised of all elements in the responder chain, this might include the touchBar property of the table row (provided it can become first responder).

    2. Are you sure that these items should be hidden when the row is not selected? Consider disabling them instead (e.g. by setting the enabled property of the buttons they contain to false).