NSMenuItem with action added to NSStatusBar is grayed out when the selected function is moved to other class
The solution was to manually set the target property to self
as @vadian and @red_menace helped me discover in the comments of the question.
The working code looks like this:
import Cocoa
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
var statusBarItemController: StatusBarItemController?
func applicationDidFinishLaunching(_ aNotification: Notification) {
// Insert code here to initialize your application
statusBarItemController = StatusBarItemController()
}
func applicationWillTerminate(_ aNotification: Notification) {
// Insert code here to tear down your application
}
}
import Cocoa
class StatusBarItemController: NSObject {
let statusBarItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.squareLength)
override init() {
super.init()
if let button = statusBarItem.button {
button.image = NSImage(named: NSImage.Name("trayIcon"))
}
constructMenu()
}
func constructMenu() {
if let button = statusBarItem.button {
button.image = NSImage(named: NSImage.Name("trayIcon"))
}
let menu = NSMenu()
let fromTheWindowsItem = NSMenuItem(
title: "From the windows...",
action: #selector(StatusBarItemController.printToTheWalls(_:)),
keyEquivalent: ""
)
fromTheWindowsItem.target = self
menu.addItem(fromTheWindowsItem)
menu.addItem(NSMenuItem.separator())
menu.addItem(NSMenuItem(
title: "Quit",
action: #selector(NSApplication.terminate(_:)),
keyEquivalent: "q"
))
statusBarItem.menu = menu
}
@objc func printToTheWalls(_ sender: NSMenuItem) {
print("To the Walls!")
}
}
StatusItem in MacOS menubar is greyed out and doesn't work
You have to set the target.
let playMenuItem = menu.addItem(withTitle: "Play Pause", action: #selector(onClickPlayPause), keyEquivalent: "1")
playMenuItem.target = self
The Quit
item works via First Responder.
NSMenuItem is not enabled swift
The target needs to be self
instead of nil.
menuItem.target = self
Adding IBOutlets to Other Class Files in Swift?
Create a XIB file or use storyboard and set it's file owner as your UI view controller. Then setup your actions and outlets there. I would recommend you watch some videos on you tube before you proceed.
NSMenuItem enabled state, dynamic naming and target action
See the NSMenuValidation protocol.
You implement -validateMenuItem:, which is used to determine whether a menu item should be enabled or disabled. It's called for each menu item just before a menu is popped up.
menu items disabled in macOS menubar App
Your Quit menu item is working "accidentally". It is not using the terminate(_:)
method you implemented. Put a print()
statement there and you'll see it's not being invoked.
A menu item either has a specific target object assigned or it uses the responder chain to search for an appropriate target. You are not assigning a target for your menu items, so they are using the responder chain. Your MenuBarActions
class is not part of the responder chain. (Classes generally can't be. Certain objects can be.) So, the menu items will never target your class.
The Quit menu works because the application object is on the responder chain and it has a terminate(_:)
method. In fact, that's what your terminate(_:)
method would invoke if it were ever being called. But the menu item is actually invoking it directly.
You should create an actual controller object (not just class) that implements the action methods and set the menu items' target
property to it.
Related Topics
3 Component Dynamic Multi UIpickerview Swift
Swift: Mkannotation Long Title Text
How to Create Generic Closures in Swift
Dynamictype of Optional Chaining Not The Same as Assignment
Swiftui Remove Transition of Fullscreen Cover
Change Color of Row Programmatically in Watchkit
Wkwebview Calayer to Image Exports Blank Image
How to Enable a Button in Different Cases in Swift
Non-Translucent UItabbar Creates Strange Grey Bar
How to Create Viewcontrollers Without Storyboard and Set One as Delegate of The Other One
How to Use Gpx File for UI Tests Only
How to Create Rounded Image with Border and Shadow as Mkannotationview in Swift
Filter, Closure, Functional Syntax Version of for Loop with Multiple Conditions
Reactive Cocoa/Reactive Swift - Swift 3.0 Missing Methods
Swift: Object Instance by Name
How to Get Unsaferawpointer on The Swift Object
How to Provide Default Implementation of an Objective-C Protocol in a Swift Protocol Extension
How to Find Multiple Nsrange for a String from Full String iOS Swift