1
votes

I have a window with an NSTableView that is populated from an NSMutableArray.

In one column I programmatically create an NSPopUpbutton and add the items and set the title according to a value in the data source array.

When the window is first drawn everything is perfect. If I use the search function or the table ever gets redrawn with [tableView reloadData] the buttons in the cell are all off and everything goes sideways.

Based on suggestions I modified the way I create the NSPopUpButton so that it isn't drawn over and over but I can't figure out why or how to stop it from getting all messed up.

I know cells are recycled but I'm lost as to how to ensure that the recycled cells are clean.

The important part of the code is below (there's a lot of other stuff but this is how I deal with the buttons)

In my header file:

@public
IBOutlet NSPopUpButton *button;

In my Implementation file I create the button as such:

- (void) awakeFromNib{
//Create popup button
button = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(2, 1, 200, 22) pullsDown:NO];
[button setBordered:YES];
[button setButtonType:NSMomentaryLightButton];
[button setBezelStyle:NSRoundedBezelStyle];
[button setHidden:YES];
[button setAction:@selector(selectedAction:)];
}

And then when the view is drawn:

- (NSView *)tableView:(NSTableView *)table_view viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
Proposal *p = [list objectAtIndex:row];
NSString *identifier = [tableColumn identifier];

NSTableCellView *cell = [table_view makeViewWithIdentifier:identifier owner:self];

if([identifier isEqualToString:@"status"]){
    cell.textField.stringValue = @"";

    if(p){
        //Check which button we need
        if ([p.status isEqualToString:@"Approved"]){
            [cell addSubview:button];
            [button addItemWithTitle:@"Pending"];
            [button addItemWithTitle:@"Completed"];
            [button addItemWithTitle:@"Rejected"];                
            [button setTitle:@"Approved"];
            [button setHidden:NO];
        }
    }
 }
 }

There's more to the code (more columns) but they aren't necessary to this so I omitted them so to be concise.

This code successfully draws the buttons and like I said everything is perfect on first draw but everything gets majorly messed up if the table ever has to reload data.

So I'm totally stumped. I've tried creating the button in IB but then I can't access it from the code to change the title or items... I've tried subclassing NSPopUpButton but I end up at the same place.

Also in macOS cells / views are reused. Since the table view is view based anyway it's more convenient to create a second (custom) cell view with popup button in the table view in Interface Builder and return the cells accordingly.vadian
If I follow- you're suggesting creating the NSPopUpButton in IB and then controlling it programmatically? I have tried that but can't seem to affect any change on the button. Calls like [button addItemWithTitle:@"Rejected"]; and [button setTitle:@"Approved"]; don't seem to do anything. Could I be binding it incorrectly?julian
No I mean a second separate NSTableCellView in Interface Builder. Drag the popup button into that second view and create the menu items. Create a custom Cocoa class file, name it for example ButtonTableCellView. Add an IBOutlet for the popup.button. Connect the button in Interface Builder. Set the class of the second table cell view to ButtonTableCellView and assign an identifier. In cellForRow if status is Approved return a ButtonTableCellView otherwise the standard NSTableCellView. The entire code in awakeFromNib and the code related to button is not needed.vadian
Ok, I think I follow and have created everything ok, but am hung up on how to return the ButtonTableCellViewjulian
Check first identifier == "status" then if status == "Approved" return ButtonTableCellView *cell = (ButtonTableCellView *)[table_view makeViewWithIdentifier:"buttonCellIdentifier" owner:self]; otherwise the standard cell. buttonCellIdentifier is the identifier of the second view.vadian