macOS context menu from an NSButton
How to display a context menu when pressing an NSButton
Currently I am developing a small utility app for the Mac as a side project, and one of the requirements is the ability to open a URL in a browser. The idea was to have a button that when pressed displays a context menu with several options which the user can select from. Kind of like a drop down menu but visually different.
I am not an expert in macOS development and I am very inexperienced when it comes to AppKit, thus what seemed like a simple task actually took me some time. So for the sake of helping out another poor soul who might be struggling like I was, I am going to show you how I managed to solve my problem. In the end the solution is extremely simple.
The Button
So, one of the UI elements that is in the app is a Button, an NSButton to be exact that when pressed should reveals a Context menu with several options.
Of course you are free to do this how ever you prefer but just note that I used a StoryBoard and connected the NSButton action to my NSViewController visually from the StoryBoard.
The result looks like this, a very simple IBAction in my NSViewController.
| |
The menu
So lets look at how to create a context menu, or more correctly an NSMenu in code from our action. Start by declaring a property at the class level. We will declare it as an Implicitly Unwrapped Optional
| |
You will also need to declare an Enum to handle the menu item selection using the tag property in the NSMenuItem you instantiate.
| |
The enum is totally optional, you can easily just hard code different integers for the tag property if you prefer.
Next, in our IBAction we will take care of instantiating the NSMenu and we will add a couple of NSMenuItem with the help of a helper function.
| |
Please note that you will need to replace MyViewController.handleMenuItemSelected with your own selector. Also note that unless you plan to handle the menu item selection via the Responders chain, you need to set the target to self otherwise your menu item will stay grayed out.
Display the context menu
The simplest way to display an NSMenu is to use the following instance method, as can be found in the developer documentation.

Thus the complete code for the NSViewController looks like so, including a demo menu item selection handler.
| |
Conclusion
As you can see by the code above, it is very easy to display a context menu when your UI requires it. By using the NSMenu::popUp(positioning:at:in:) instance method we can specify exactly where we want the NSMenu to appear.