macOS Swift: tab to an NSPopUpButton

So you have a form in your app, and you want to tab from an NSTextField to an NSPopUpButton. You know, like any normal HTML form would using the tabindex attribute.

Well, you could use the dandy nextKeyView property, which lets you define which input should get focus next after tabbing. You could do it like this:

class RightViewController: NSViewController {

  @IBOutlet var rageTextField: NSTextField!
  @IBOutlet var furyPopup: MyNSPopUpButton!

  override func viewDidLoad() {
    super.viewDidLoad()
    self.rageTextField.nextKeyView = furyPopup
  }
}

It won’t work. It’ll work fine between NSTextFields and other stuff, but not your NSPopUpButton. Why? Well, [INSERT INCOHERENT SEETHE-RANTING HERE]. That’s why.

Look, the short explanation is that with NSPopUpButtons, canBecomeKeyView is set to false. Fix it by overriding using a subclass.

class MyNSPopUpButton: NSPopUpButton {
  override var canBecomeKeyView: Bool {return true} // @&$('#$')!!
}

class ViewController: NSViewController {

  @IBOutlet var rageTextField: NSTextField!
  @IBOutlet var furyPopup: MyNSPopUpButton! // <-- LOOK AT THE "MY"

  override func viewDidLoad() {
    super.viewDidLoad()

    print("(furyPopup.canBecomeKeyView)") // should be true

    self.rageTextField.nextKeyView = furyPopup // should work now
  }
}

Wait, one more thing. Don’t forget to change the popup’s class in IB, too:

Make an OSX install USB drive quick

Surprisingly, Apple has actually made this pretty easy. <aside>I’m enjoying the Tim Cook reign so far. But that’s a whole separate post.</aside> This works for Yosemite and El Capitan, and I’m assuming future versions too.

Make sure you have the installer downloaded from the app store. It will delete itself after you use it, but you can download it again.

Format an 8 GB flash drive and plug the thing in. Leaving it named “Untitled” is easiest, but you can change it. Just make sure to change any instances of “Untitled” in the command line below.

For El Capitan, Bust our your Terminal, and copypaste this:

sudo /Applications/Install\ OS\ X\ El\ Capitan.app/Contents/Resources/createinstallmedia --volume /Volumes/Untitled --applicationpath /Applications/Install\ OS\ X\ El\ Capitan.app --nointeraction

Pretty much the same for Yosemite:

sudo /Applications/Install\ OS\ X\ Yosemite.app/Contents/Resources/createinstallmedia --volume /Volumes/Untitled --applicationpath /Applications/Install\ OS\ X\ Yosemite.app --nointeraction

 

Star Trek crew dancing like it's 1969