1

I currently have a NSStatusBar with a NSStatusBarItem with a title displaying. But I wan't to replace the title/text with a custom NSView. How can I do that?

I currently have:

func applicationDidFinishLaunching(_ aNotification: Notification) {
    let statusBar = NSStatusBar.system
    statusBarItem = statusBar.statusItem(withLength: NSStatusItem.variableLength)
    statusBarItem.button?.title = "My Menu Bar App"
}

Let's say I wan't to replace the title with the following:

let view = NSView(frame: NSRect(x: 0, y: 0, width: 40, height: 40))
view.layer?.backgroundColor = NSColor.yellow.cgColor

How can I achieve that? I tried to add it as a subview to the button, with no luck.

eivindml
  • 2,197
  • 7
  • 36
  • 68
  • Add the view to the subviews of the button – vadian Feb 03 '20 at 09:32
  • @vadian As I wrote: " I tried to add it as a subview to the button, with no luck." – eivindml Feb 03 '20 at 09:37
  • The reason is something else: Unlike `UIView` you have to enable the layer in `NSView` with `view.wantsLayer = true`. Consider also that the height of the custom view is restricted to the height of the status bar. – vadian Feb 03 '20 at 09:43
  • I have added `.wantsLayer = true` to both the view and the button, but still nothing showing. Just a blank clickable square, but don't see any color. – eivindml Feb 03 '20 at 09:45
  • I'm also using the `statusBarItem = statusBar.statusItem(withLength: NSStatusItem.squareLength)` for a fixed size. – eivindml Feb 03 '20 at 09:46
  • I tested quickly the configuration. It works, I see a yellow square – vadian Feb 03 '20 at 09:52
  • Could you maybe post the entire thing as an answer or a gist, so I can compare? :) – eivindml Feb 03 '20 at 09:52

1 Answers1

6
  • Create a strong reference to the status item on the top level of the class

    let statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
    
  • in applicationDidFinishLaunching enable the layer and add the view to the subviews of the button

    func applicationDidFinishLaunching(_ aNotification: Notification) {
    
        let view = NSView(frame: NSRect(x: 0, y: 0, width: 22, height: 22))
        view.wantsLayer = true
        view.layer?.backgroundColor = NSColor.yellow.cgColor
        statusItem.button?.addSubview(view)
    
    }
    
vadian
  • 274,689
  • 30
  • 353
  • 361
  • Thank you! It works. My issue was that I was setting `view.wantsLayer = true` after `view.layer?.backgroundColor`. It has to go before to work. – eivindml Feb 03 '20 at 09:58