Eytan Schulman
Eytan Schulman

Reputation: 566

NSTableView delegate not working/not filling cells

I have an NSTableView in my application, that I am loading data in after the user has typed a letter in an NSTextField.

Here are my NSTableView delegate methods

-(NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
    NSLog(@"%lu rows!", (unsigned long)contactsArr.count);
    return contactsArr.count;
}
-(NSInteger)numberOfColumns:(NSTableView *)tableView {
    return 1;
}

-(NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{

    NSLog(@"filling tableview yo");

     NSTableCellView *result = [tableView makeViewWithIdentifier:tableColumn.identifier owner:self];

    NSButton *nameField = [result viewWithTag:10];

    NSButton *numberField = [result viewWithTag:20];

    ABPerson *indexedPerson = contactsArr[row];

    [nameField setStringValue:[NSString stringWithFormat:@"%@ %@",[indexedPerson valueForKey:kABFirstNameProperty]
                               ,[indexedPerson valueForKey:kABLastNameProperty]]];

    [numberField setStringValue:[NSString stringWithFormat:@"%@",[indexedPerson valueForKey:kABPhoneProperty]]];


    if (result == nil) {

        result = [[NSTableCellView alloc] initWithFrame:CGRectMake(0, 0, 267, 52)];

        result.identifier = @"cell";
    }

    return result;

}

I have checked that my delegate and datasource are both set to this class. I also made sure my outlet is setup. When the user inputs something in the keyboard I reset the NSMutableArray to the search results and I am logging the fact that there are in fact ABPerson objects in the array. The problem is that no cells are appearing on screen. The viewForTableColumn method only runs sometimes. reloadData does not work at all.

Upvotes: 1

Views: 1073

Answers (1)

meda
meda

Reputation: 45500

You kind of have it reversed, the very first thing to do is to check if NSTableviewCell is null before populating.

Otherwise you will be creating a new cell at the end of the delegate method and return them blank

-(NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
    NSLog(@"filling tableview yo");
    NSTableCellView *result = [tableView makeViewWithIdentifier:tableColumn.identifier owner:self];

    if (result == nil) {
        result = [[NSTableCellView alloc] initWithFrame:CGRectMake(0, 0, 267, 52)];
        result.identifier = @"cell";
    }

    NSButton *nameField = [result viewWithTag:10];
    NSButton *numberField = [result viewWithTag:20];
    ABPerson *indexedPerson = contactsArr[row];

    [nameField setStringValue:[NSString stringWithFormat:@"%@ %@",[indexedPerson valueForKey:kABFirstNameProperty]
                               ,[indexedPerson valueForKey:kABLastNameProperty]]];

    [numberField setStringValue:[NSString stringWithFormat:@"%@",[indexedPerson valueForKey:kABPhoneProperty]]];

    return result;
}


EDIT:

I added a version with a custom cell, I find it cleaner then using view tags, everytime you need to customize a cell beyond the basic, you will be better of sublassing NSTableViewCell. and no need to check for nulls, make sure you assign identifier as well

- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {

    NSLog(@"filling tableview yo");
    PersonTableCellView *cellView = [tableView makeViewWithIdentifier:tableColumn.identifier owner:self];

    // Just in Case you got multiple columns
    if( [tableColumn.identifier isEqualToString:@"cell"] )
    {
        ABPerson *indexedPerson = contactsArr[row];
        NSString *nameInfo = [NSString stringWithFormat:@"%@ %@",
                                 indexedPerson[kABFirstNameProperty],
                                 indexedPerson[kABLastNameProperty]];
        NSString *numberInfo =   indexedPerson[kABPhoneProperty];

        NSLog(@"nameInfo = %@, numberInfo = %@", nameInfo, numberInfo);
        //set the strings
        cellView.nameField.stringValue = indexedPerson
        cellView.numberField.stringValue = bugDoc.data.title;

        return cellView;
    }
    return cellView;
}

Upvotes: 1

Related Questions