views:

44

answers:

2

Hey all,
I have this bizarre problem. I'm making a checklist program with XCode and I'm using UITableView with UITableViewCellAccessoryCheckmark. I can select cells and the checkmark will appear, but somehow, other cells that I have NOT yet selected below will also have a checkmark appear. Any ideas?
Here's my check mark coding:

- (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell;
cell = [aTableView cellForRowAtIndexPath: indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark; 

}

I don't know if this affects it, but I also implemented this method:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

static NSString *CellIdentifier = @"CellIdentifier";

// Dequeue or create a cell of the appropriate type.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    cell.accessoryType = UITableViewCellAccessoryNone;
}

// Configure the cell.
if(tableView == Table1){

    switch(indexPath.section){
        case 0:
            cell.textLabel.text = [array1 objectAtIndex:indexPath.row];
            break;
        case 1:
            cell.textLabel.text = [array2 objectAtIndex:indexPath.row];
            break;
        case 2:
            cell.textLabel.text = [array3 objectAtIndex:indexPath.row];
            break;
    }

    //cell.textLabel.text = [NSString stringWithFormat:@"Row %d", indexPath.row];
}
if(tableView == Table2){
    cell.textLabel.text = [array4 objectAtIndex:indexPath.row];
}
return cell;

}

Thanks.

A: 

Set the cell.accessoryType each time you call tableView:cellForRowAtIndexPath:. Otherwise, when you reuse a cell, you'll get it's accessoryView instead of what you're expecting.

So, yeah, you'll need to keep track in when NSIndexPaths are selected by some method other than just looking at the accessoryType.

Jablair
Sorry, but can you give an example of how I would reset the cell.accessoryType? Are you telling me to keep a list of selected cells and show their accessory type accordingly each time tableView:cellForRowAtIndexPath: is called?
CSwat
Yeah, keep a list of the selected cells, or come up with some other data structure for tracking the info. Michael's idea of using putting a dictionary in your array with keys for text and selected is one technique I've used. Then set the accessory type at the same time you set the cell title.You need to set the accessory type each time because you're not creating a new cell for each row - you're often reusing an existing (offscreen) cell. And don't think about going away from reusing existing cells - there are real performance gains by limiting the cell allocations.
Jablair
A: 

You should keep the checked/unchecked info in data source (array).

I also advise you to remove the cell.accessoryType = UITableViewCellAccessoryNone; line.
This line will be executed only for few first cells. All the other cells will be "reused" - meaning that the old (already initiated) cells will be used, and you will have to modify the details that are displayed on these cells (all inside cellForRowAtIndexPath as you do now).

In addition you will have to add a similar line (something like cell.accessoryType = ([[array objectAtIndex:indexPath.row] boolValue] ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;).

In general, I suggest you to use one array for holding the data for your table, when each item in the array will be a dictionary. This way you will be able to hold the texts and the boolean checkmarks (inside NSNumber) and easily access them when needed.

Michael Kessler