开发者

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:

How can I create a NSPopUpButton that uses a fixed Image, and no arrows?

How can I create a NSPopUpButton that uses a fixed Image, and no arrows?

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.

  1. drag the standard NSPopUpButton to your window,
  2. select the Style as whatever type of button you want,
  3. chose the button to have an image but don't set the image,
  4. 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜