2

I am building a NSTouchBar for my app using storyboard.

I want to replace the ESC button with something else.

As usual, there is no doc telling you how to do that.

I have searched the web and I have found vague informations like

You can change the content of "esc" to something else, though, like "done" or anything, even an icon, by using escapeKeyReplacementItemIdentifier with the NSTouchBarItem.

But this is too vague to understand.

Any ideas?


This is what I did so far.

I have added a button to NSTouchBar on storyboard and changed its identifier to newESC. I added this line programmatically:

self.touchBar.escapeKeyReplacementItemIdentifier = @"newESC";

When I run the App the ESC key is now invisible but still occupies its space on the bar. The button that was supposed to replace it, appears next to it. So that bar that was

`ESC`, `NEW_ESC`, `BUTTON1`, `BUTTON2`, ...

is now

`ESC` (invisible), `NEW_ESC`, `BUTTON1`, `BUTTON2`, ...

The old ESC is still occupying its space on the bar.

Duck
  • 34,902
  • 47
  • 248
  • 470
  • The header NSTouchBar.h has some attempt at documentation. The comments aren't proper headerdocs, so I guess they didn't make it to the published docset. – jscs Jul 01 '17 at 14:56
  • 1
    Apple should refrain from writing docs, they are all crap. I have read that and still don't know how to do it. – Duck Jul 01 '17 at 15:02
  • "should refrain" I mean, they basically already do! :P – jscs Jul 01 '17 at 15:03
  • I mean completely. It is obvious by now that they treat developers as 3rd class citizens. They despise us and MacOS developers even more. – Duck Jul 01 '17 at 15:04

1 Answers1

2

This is done by creating a touch bar item, let's say a NSCustomTouchBarItem containing a NSButton, and associating this item with its own identifier.

Then with another identifier you do your usual logic but you add the previously created identifier as the ESC replacement.

Quick example in Swift:

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

    switch identifier {
    case NSTouchBarItemIdentifier.identifierForESCItem:
        let item = NSCustomTouchBarItem(identifier: identifier)
        let button = NSButton(title: "Button!", target: self, action: #selector(escTapped))
        item.view = button
        return item
    case NSTouchBarItemIdentifier.yourUsualIdentifier:
        let item = NSCustomTouchBarItem(identifier: identifier)
        item.view = NSTextField(labelWithString: "Example")
        touchBar.escapeKeyReplacementItemIdentifier = .identifierForESCItem
        return item
    default:
        return nil
    }

}

func escTapped() {
    // do additional logic when user taps ESC (optional)
}

I also suggest making an extension (category) for the identifiers, it avoids making typos with string literals:

@available(OSX 10.12.2, *)
extension NSTouchBarItemIdentifier {
    static let identifierForESCItem = NSTouchBarItemIdentifier("com.yourdomain.yourapp.touchBar.identifierForESCItem")
    static let yourUsualIdentifier = NSTouchBarItemIdentifier("com.yourdomain.yourapp.touchBar.yourUsualIdentifier")
}
Eric Aya
  • 69,473
  • 35
  • 181
  • 253
  • haha... things are getting worse... I have created [this other question](https://stackoverflow.com/questions/44866666/make-a-nsobject-class-be-the-nextresponder-is-that-possible-or-is-that-anothe) to deal with the fact that the `NSTouchBar` delegate methods are not firing... if I solve this other one, your question will probably work and it will solve this question... it is a combo... – Duck Jul 02 '17 at 01:15
  • btw what is `yourUsualIdentifier` and shouldn't´t you be calling `touchBar.escapeKeyReplacementItemIdentifier` from inside the first case block, the block that represents the esc? – Duck Jul 03 '17 at 06:01
  • 1
    yourUsualIdentifier is just an example of another identifier for an item, here a text field. And since the ESC replacement is a property on the `touchbar`, it doesn't matter where you call it from. – Eric Aya Jul 03 '17 at 07:16
  • An objective.c version? Thanks – Joannes Sep 04 '17 at 11:31