How to add multiple menu items with the same title to NSPopUpButton(NSMenu)?
Asked Answered
L

4

7

As docs say it's impossible to add two menu items to NSPopUpButton if they both have the same title. I was trying to add menu items to [popupButton menu], but with no luck. I was also trying to create a new menu, add items to it and then use [popupButton setMenu:newMenu], but no. Menu always display only one item per name.

But I know it should be possible, if you try to create a smart playlist in iTunes, you could select "Playlist" from the left popup button, "=" from the middle, and the right one will hold menu items for every playlist in iTunes EVEN if they have the same title. So how do they do it?

Loma answered 23/2, 2010 at 16:56 Comment(0)
P
1

I had the exact problem and it was solved easily. Instead of using NSPopUpButton methods such as –addItemWithTitle: to manipulate the button items, I added an NSArrayController and added the items into the array controller instead. Then I used the bindings to bind the controller and the popup button and now it shows items with same titles.

To do the bindings:

  1. Add an NSArrayController in IB.
  2. Set the NSPopUpButton bindings for "Content" to Array Controller with the "Controller Key" being "arrangedObjects"
  3. Set the NSPopUpButton bindings for "Selected Index" to Array Controller with the "Controller Key" being "selectionIndex"
  4. [Optional] Select the array controller and set the Class Name in attributes to whatever class your items are e.g. NSString or you can use the default NSMutableDictionary and add keys in the box below which consequently lets you wrap your items in a dictionary and add different keys for what you want to show in popup button and what you want to have in background. To set which key of the dictionary you want to be reflected in the popup button, go to popup button's bindings for "Content" again and set the "Modal key Path" to the key you added in the array controller attribute.
Protectorate answered 1/3, 2010 at 21:36 Comment(0)
H
5

While NSPopUpButton methods like addItemWithTitle: and addMenu: won't allow duplicate names, it is definitely possible to have items with the same title. You simply have to set the name on the NSMenuItem itself.

For example, if you have an array of strings (like playlist names perhaps) you want to add them to a popup button, and want to make sure duplicates will be in there, do it like this:

NSArray* items = [NSArray arrayWithObjects:@"Foo", @"Bar", @"Baz", @"Foo", nil];

for (NSString* item in items)
{
   [popupButton addItemWithTitle:@"blah"];
   [[popupButton lastItem] setTitle:item];
   [[popupButton lastItem] setTarget:self];
   [[popupButton lastItem] setAction:@selector(something:)];
}
Him answered 24/2, 2010 at 6:39 Comment(3)
Ken I tried this approach also. But the result is the same. Maybe because my popup button is in NSPredicateEditorRowTemplate and it is post processed by its predicate editor. I'd like to see some source code where this method works.Loma
I'm doing this in one of my apps and it does work. That's where I got the code that I simplified above. I had to do it this way because the menu lists user-named preset settings and duplicates had to be allowed. I've never used the predicate editor so I can't help there. Sorry!Him
PS: If you want to see it work, just make a new test project with a popup button and paste in that code.Him
W
4

Instead of using addItemWithTitle:, you can create an NSMenuItem manually and add it directly to the menu. This allows you to specify any title you want, as well as being able to insert it at any location in the menu.

NSMenuItem* newItem = [[NSMenuItem alloc] initWithTitle:@"foo" action:@selector(something:) keyEquivalent:@""];

[newItem setTarget:self];
[[popupButton menu] addItem:newItem];
[newItem release];
Woodberry answered 25/2, 2010 at 0:0 Comment(2)
This doesn't solve the problem. NSPopUpButton will behave exactly as if NSPopUpButton's addItemWithTitle:title was used: One item will be displayed for each unique title.Resect
This totally worked for me just now (macOS 10.15+). You can't mix NSMenuItems and itemsWithTitle in the same NSPopupButton! Hey Brian, whassup!Gutbucket
P
1

I had the exact problem and it was solved easily. Instead of using NSPopUpButton methods such as –addItemWithTitle: to manipulate the button items, I added an NSArrayController and added the items into the array controller instead. Then I used the bindings to bind the controller and the popup button and now it shows items with same titles.

To do the bindings:

  1. Add an NSArrayController in IB.
  2. Set the NSPopUpButton bindings for "Content" to Array Controller with the "Controller Key" being "arrangedObjects"
  3. Set the NSPopUpButton bindings for "Selected Index" to Array Controller with the "Controller Key" being "selectionIndex"
  4. [Optional] Select the array controller and set the Class Name in attributes to whatever class your items are e.g. NSString or you can use the default NSMutableDictionary and add keys in the box below which consequently lets you wrap your items in a dictionary and add different keys for what you want to show in popup button and what you want to have in background. To set which key of the dictionary you want to be reflected in the popup button, go to popup button's bindings for "Content" again and set the "Modal key Path" to the key you added in the array controller attribute.
Protectorate answered 1/3, 2010 at 21:36 Comment(0)
B
0

Swift 5 Add using guaranteed unique title, then alter title in next statement.

  • "accountPU" is NSPopUpButton object
  • "from" is an account object.
    accountPU.addItem(withTitle: "\(from.accountID!)")      
    accountPU.lastItem!.title = from.name
Betaine answered 10/11, 2021 at 1:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.