Dynamically populating an NSPopUpButtonCell in an NSTableView

Cocoa, General

It is quite common. You have a PopUpButton (NSPopUpButtonCell) in an NSTableView and you want to dynamically change the contents based on the selected row:

Popupcellpicture1

How do you do this? There are a few tricky steps. First, add a menu to the nib and set the delegate for the menu to be your Controller:

Menusdelegatepopupbutton

Okay. Next is the tricky part. In IB, when you have a column in a tableview selected, it has a little white triangle in the corner:

Picture 1-3

Clicking on that will allow you to modify properties of the cell (in this case, the NSPopUpButtonCell). However, we want to set the menu for the NSPopUpButtonCell, so drag from that little triangle to your menu and set the menu outlet:

Popupcellhookup

Okay, good! Now, all your controller needs is a little bit of code to dynamically populate the menu:

– (void)menuNeedsUpdate:(NSMenu *)menu {

    // remove all previous items

    while ([menu numberOfItems] > 0) {

        [menu removeItemAtIndex:0];

    }

    // dynamically build the menu

    int i;

    int selectedRow = [tableViewStuff selectedRow];

    for (i = 0; i <= selectedRow; i++) {

        NSMenuItem *item = [[NSMenuItem alloc] 

            initWithTitle:[NSString stringWithFormat:@“Menu %d”, i] 

                   action:@selector(menuClicked:) keyEquivalent:@“”];

        [item setTarget:self];

        [menu addItem:item];

    }

}

Okay, that should work, right? Normally, yes. But in a tableview when a cell is tracked, it is first copied. Unfortunately, a small bug in the menu code doesn’t copy the delegate. Therefore, we must fix it up in the nstableview’s delegate method:

– (void)tableView:(NSTableView *)tableView 

  willDisplayCell:(id)cell 

   forTableColumn:(NSTableColumn *)tableColumn 

              row:(int)row 

{

    if ([cell isKindOfClass:[NSPopUpButtonCell class]]) {

        [[cell menu] setDelegate:self];

    }

}

That’s it! Have fun…happy coding.

Previous Post
no_thumbnail
Delphi easter eggs
Next Post
no_thumbnail
Drag and Drop in an NSTableView

10
Leave a Reply

avatar
500
9 Comment threads
1 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
5 Comment authors
corbintwocranesmichaelcorbinLemondash Recent comment authors
  Subscribe  
Notify of
Lemondash
Guest

You write “In IB, when you have a column in a tableview selected, it has a little white triangle in the corner”. In fact it doesn’t. Not until you added a NSPopUpButtonCell to it. That’s a little confusing in your tutorial.

btw: you make beautiful boxes :-)

michael
Guest
michael

cool, but how i can set an menuitem (checked the selected item) ???

twocranes
Guest
twocranes

The same uncopied delegate affects NSOutlineView, but the fix for that involves the analogous delegacy method outlineView: willDisplayCell: forTableColumn: item:

I note that XCode 2.5 (ca 2007) continues to feature this bug…

twocranes
Guest
twocranes

I did! 7501762 (something about dropped delegate)

twocranes
Guest
twocranes

“But in a tableview when a cell is tracked, it is first copied”

Apparently a deep copy that clones the menu and breaks my code.

I have several cells, varying by row, reflecting different row content – each with a different menu.

My code in the menu delegate method menuNeedUpdate depends on the original cells menu object reference value to distinguish what menu it is updateing, a copy (into a different zone) is ‘none of the above’ and is not helpful.

twocranes
Guest
twocranes

“But in a tableview when a cell is tracked, it is first copied”. Your fix for the dropped delegate is working, but this explanation seems unsupported by what I see debugging. my mixedRowTC supplys row-specific cells using an NSTableColumn subclass as you show elsewhere. It logs each supplied cell as shown below. I am also logging the delegate-patched cells as they are fixed. Same object is seen. Cant be a copy, %@ object descriptions show matching id’s. OM2[747] mixedRowTC row 1, cell OM2[747] fix cell I fully believe the menu is being cloned, and wonder to what end (beyond my… Read more »

twocranes
Guest
twocranes

Please feel free to edit this narative down, I should have protected the log entries in 8 useing code tags, here they are again.


OM2[993] mixedRowTC row 1, cell
OM2[993] fix cell

twocranes
Guest
twocranes

ok, it seems angle brackets are a bad thing, even protected by code tags; third try,

OM2[993] mixedRowTC row 1, cell [NSPopUpButtonCell: 0x399b20]
OM2[993] fix cell [NSPopUpButtonCell: 0x399b20]

(c) 2008-2019 Corbin Dunn

Privacy Policy

Subscribe to RSS feeds for entries.

104 queries. 0.851 seconds.

Log in