I'm trying to get NSPopUpButton
to render like a standard NSButton
with only an image set, but not having any luck.
Much like the "+" button in Mail.app:
I assume they did this with NSPopUpButton
. The obvious thing I've tried is:
NSMenuItem *imageItem = [[[NSMenuItem alloc] init] autorelease];
[imageItem setImage:[NSImage imageNamed:NSImageNameAddTemplate]];
[[popUpButton cell] setUsesItemFromMenu:NO];
[[popUpButton cell] setMenuItem:imageItem];
[[popUpButton cell] setImagePosition:NSImageOnly];
This doesn't show the image however, instead it just shows a pair of arrows (I suspect they're drawn over where the image would be). Calling [popUpButton setImage:...]
also does nothing.
Is there a documented way to do this, or does it come down to some custom subclassing?
To prevent the button from displaying the arrow:
[popupButton.cell setArrowPosition:NSPopUpNoArrow];
Here is the code I used to finally get this working in Swift (modeled after Apple's Menu Madness demo app).
func setUpButton() {
let popupButton = NSPopUpButton()
popupButton.translatesAutoresizingMaskIntoConstraints = false
popupButton.pullsDown = true
popupButton.bordered = false
let popupCell = popupButton.cell as! NSPopUpButtonCell
popupCell.arrowPosition = NSPopUpArrowPosition.NoArrow
popupButton.addItemWithTitle("")
var item = popupButton.itemAtIndex(0)
item?.image = NSImage(named: "add")
item?.onStateImage = nil
item?.mixedStateImage = nil
popupButton.addItemWithTitle("Item1")
item = popupButton.itemAtIndex(1)
item?.action = #selector(item1Pressed)
item?.target = self
popupButton.addItemWithTitle("Item2")
item = popupButton.itemAtIndex(2)
item?.action = #selector(item2Tapped)
item?.target = self
self.addSubview(popupButton)
// NOTE: These are auto layout helper methods I made that you won't have.
// Just note that here is where I set up the auto layout constraints.
popupButton.widthConstraint(40)
popupButton.heightConstraint(20)
popupButton.centerVerticallyInSuperview()
popupButton.trailingSpaceToSuperview(0)
}
// TO MAKE SURE ALL ITEMS ALWAYS VALID (WHAT I WANTED FOR MY USE CASE)
override func validateMenuItem(menuItem: NSMenuItem) -> Bool {
return true
}
func item1Pressed() {
// do stuff
}
func item2Pressed() {
// do stuff
}
Be sure to make the width/height of the button big enough for the image. I found there was some padding on the right side of the button that covered my small image until I made the button wide enough to accommodate the mysterious padding.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With