How can I create a NSPopUpButton that uses a fixed Image, and no arrows?
I'm trying to get NSPopUpButton
to render like a standard NSButton
with only an开发者_如何学C 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.
In your example, yes it is probably implemented with an NSPopUpButton
, but rather than trying to customize the cell, what you really want is a button with -pullsDown:
set to YES
.
This is easiest to set up in Interface Builder. Even easier, use BWToolkit which features a button bar and custom buttons specifically for this purpose.
@Laurent Etiemble's (now deleted) answer helped me and the OP.
Take a look at this thread and the Apple's sample Menu Madness: they contains some sample code to put an image on a
NSPopUpButton
.
In Xcode 4.4 you can do all this by using Interface Builder.
- drag the standard
NSPopUpButton
to your window, - select the Style as whatever type of button you want,
- chose the button to have an image but don't set the image,
- drag an
NSImage
of whatever icon you want on top of the button.
I found that using the NSImage
instead of setting the image of the button worked much better. Setting the button image caused problems when selecting items in the popup menu.
精彩评论