Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I change/modify the displayed title of an NSPopUpButton

I would like an NSPopUpButton to display a different title than the title of the menu item that is selected.

Suppose I have an NSPopUpButton that lets the user pick a list of currencies, how can I have the collapsed/closed button show only the currencies abbreviation instead of the menu title of the selected currency (which is the full name of the currency)?

I imagine I can override draw in a subclass (of NSPopUpButtonCell) and draw the entire button myself, but I would prefer a more lightweight approach for now that reuses the system's appearance.

The menu items have the necessary information about the abbreviations, so that's not part of the question.

like image 553
Thomas Krajacic Avatar asked Oct 27 '25 05:10

Thomas Krajacic


1 Answers

Subclass NSPopUpButtonCell, override drawTitle(_:withFrame:in:) and call super with the title you want.

override func drawTitle(_ title: NSAttributedString, withFrame frame: NSRect, in controlView: NSView) -> NSRect {
    var attributedTitle = title
    if let popUpButton = self.controlView as? NSPopUpButton {
        if let object = popUpButton.selectedItem?.representedObject as? Dictionary<String, String> {
            if let shortTitle = object["shortTitle"] {
                attributedTitle = NSAttributedString(string:shortTitle, attributes:title.attributes(at:0, effectiveRange:nil))
            }
        }
    }
    return super.drawTitle(attributedTitle, withFrame:frame, in:controlView)
}

In the same way you can override intrinsicContentSize in a subclass of NSPopUpButton. Replace the menu, call super and put the original menu back.

override var intrinsicContentSize: NSSize {
    if let popUpButtonCell = self.cell {
        if let orgMenu = popUpButtonCell.menu {
            let menu = NSMenu(title: "")
            for item in orgMenu.items {
                if let object = item.representedObject as? Dictionary<String, String> {
                    if let shortTitle = object["shortTitle"] {
                        menu.addItem(withTitle: shortTitle, action: nil, keyEquivalent: "")
                    }
                }
            }
            popUpButtonCell.menu = menu
            let size = super.intrinsicContentSize
            popUpButtonCell.menu = orgMenu
            return size
        }
    }
    return super.intrinsicContentSize
}
like image 81
Willeke Avatar answered Oct 29 '25 22:10

Willeke



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!