UITableView indexPath section logic

eric.mitchell picture eric.mitchell · Dec 2, 2011 · Viewed 10.8k times · Source

This is the abridged code for my cellForRowAtIndexPath UITableView delegate method:

- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"blahblahblah"];
if (cell == nil) {
    // No cell to reuse => create a new one
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"blahblahblah"] autorelease];
}
cell.textLabel.text = @"";
cell.detailTextLabel.text = @"";
cell.backgroundView = NULL; //problem here

// Initialize cell
//blah blah blah
//now to the good part...

if(indexPath.section == 1) {
    cell.backgroundView = deleteButton;
    cell.userInteractionEnabled = YES;
    cell.textLabel.text = nil;
    cell.detailTextLabel.text = nil;
}

else if(indexPath.section == 0) {
    NSLog(@"section: %i row: %i", indexPath.section, indexPath.row);
    switch (indexPath.row) {
        case 0:
            cell.textLabel.text = @"foobar";
            //more stuff
            break;

        //lots more cases

        default:
            break;
    }
}

return cell;

}

My problem is that the first cell in section 1 (section 0 has 10 cells, section 1 has only 1 cell) is getting assigned the information that is only supposed to be assigned to cell 0 of the first section. So, instead of getting the deleteButton background and etc, it gets the label title "foobar". I'm not really sure why this is happening, because my if statements are pretty clear. Any ideas?

Edit: setting the backgroundView to NULL causes those cells with text to, when they leave the view, come back without any background. So that isn't a viable solution. Also, the text for the detailTextLabel is still set on the cell that shouldn't have any text.

This is how it looks, with the cell backgroundViews set to nil and the text showing up on the delete cell where it shouldn't:

enter image description here

Solution, as recommended by Alex Deem (replacing old dequeue code with this code):

NSString* identifier;
if(indexPath.section == 0)
    identifier = @"0";
else
    identifier = @"1";
UISwitch *switchView;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
    // No cell to reuse => create a new one
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:identifier] autorelease];

Answer

Alex Deem picture Alex Deem · Dec 2, 2011

You should read the documentation regarding the reuse of cells.

You should be using a different reuseIdentifier for each of the two sections, since they are fundamentally differently styled cells.