eric.mitchell
eric.mitchell

Reputation: 8845

UITableView indexPath section logic

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];

Upvotes: 5

Views: 10774

Answers (3)

jb007
jb007

Reputation: 311

Your code is structured wrong.

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"blahblahblah"];
if (cell == nil) 

dqueueReuseableCellWithIdentifier will return an existing previously created cell if it is no longer in use. If cell == nil you should create a new cell and set defaults common to all cells. However any setting of data unique to that indexPath should be done after the

if(cell==nil) block.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"blahblahblah"];
if (cell == nil) 
{
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1         reuseIdentifier:@"blahblahblah"] autorelease];
}
cell.textLabel.text=@"unique text";
return cell;

Upvotes: 0

Alex Deem
Alex Deem

Reputation: 4805

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.

Upvotes: 5

Michael Dautermann
Michael Dautermann

Reputation: 89509

add a closing } bracket to these lines of code:

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

and I suspect you will have better results in your table.

The way things are working right now (at least as far as I can tell in your code), you create one cell and it gets initialized to something. It never gets reset to the values & data of anything else that's being requested.

Upvotes: 0

Related Questions