Setup: I have a property called "_itemListArray(ivar)", that is set to a list of "Item(NSString itemName, NSString itemPrice)". I populate a UITableView with these items and the user can select multiple rows, displaying a checkmark on that row. The indexPath of the checked cell is stored to an IVAR(_selectedItemRows). If the user selects the row again, the checkmark accessory is set to none and the indexPath is removed from the IVAR(_selectedItemRows). In "cellForRowAtIndexPath" I check the currently queued indexPath against all indexPaths in _selectedItemRows(array of indexPaths of checked cells). If the index path is in array, I check the dequeued cell, if not, I uncheck it.

Problem: The checkmark accessory is set correctly(didSelectRowAtIndexPath), but when I scroll, it acts funky. For example, if I check the first cell then scroll down, then scroll back up to the first cell, nslogs have verified that my program knows to check the cell, but it doesn't seem to.
Also, if I check 2 or more cells, scroll down, then scroll back up, usually the last cell is the only checked.

Code:

@implementation  
@synthesize itemListArray = _itemListArray;  
@synthesize selectedItemRows = _selectedItemRows;  
-(void)setItemListArray:(NSArray *)itemListArray  
{  
    _itemListArray = itemListArray;  
    [_propTableView reloadData];  
}  
- (void)viewDidLoad  
{  
    [super viewDidLoad];  
    _selectedItemRows = [[NSMutableArray alloc] init];  
}  
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section  
{  
    // Return the number of rows in the section.  
    return [_itemListArray count];  
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath  
{  
    static NSString *CellIdentifier = @"Item Selected Reuse"; //Identifier of prototype cell  
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];     

    if (nil == cell) { //If somethong goes wrong, all hell breaks loose.  
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];  
         NSLog(@"%s", __PRETTY_FUNCTION__);  
    }  
    // Configure the cell...  
    Item *curItem = [_itemListArray objectAtIndex:indexPath.row]; //Get the model information at row location.  
    cell.textLabel.text = curItem.itemName; //Set the name of the item in title field  
    cell.detailTextLabel.text = curItem.itemPrice; //Set the price of the item in the detail field.  
    for(NSIndexPath * elem in _selectedItemRows)
    { //Enumerate through checked cells  
        //NSIndexPath *ip = [_selectedItemRows objectAtIndex:x];  
        if ([indexPath compare:elem] == NSOrderedSame) { //If the current cell index path ='s any index path in the array of checked cells, check this cell.  
            cell.accessoryType = UITableViewCellAccessoryCheckmark;   
        } else {  
            cell.accessoryType = UITableViewCellAccessoryNone;  
        }  
    }  
    return cell;  
}  
//pragma mark - Table view delegate  
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath  
{  
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; //Get cell clicked on.   
    if(cell.accessoryType == UITableViewCellAccessoryNone){ //When selected, if the cell is checked, uncheck it.  
        cell.accessoryType = UITableViewCellAccessoryCheckmark;  
        [_selectedItemRows addObject:indexPath]; //Add the index path of checked cell into array to use later for comparisons  
    } else {  
        if(cell.accessoryType == UITableViewCellAccessoryCheckmark){ //If the cell is checked, uncheck it when clicked on  
            cell.accessoryType = UITableViewCellAccessoryNone;  
            [_selectedItemRows removeObject:indexPath]; //Remove that index path of unchecked cell from index array  
        }  
    }  
    [tableView deselectRowAtIndexPath:indexPath animated:YES];//Deselect row after done.  
}  
@end  
//Other code left out for brevity sake  

有帮助吗?

解决方案

You have a logic error in your code. Think about what happens in this bit of code:

for(NSIndexPath * elem in _selectedItemRows)
{ //Enumerate through checked cells  
    //NSIndexPath *ip = [_selectedItemRows objectAtIndex:x];  
    if ([indexPath compare:elem] == NSOrderedSame) { //If the current cell index path ='s any index path in the array of checked cells, check this cell.  
        cell.accessoryType = UITableViewCellAccessoryCheckmark;   
    } else {  
        cell.accessoryType = UITableViewCellAccessoryNone;  
    }  
}  

Unless the index path for the current row happens to be the last one in _selectedItemRows the cell will have the checkmark cleared. It will set the check mark when it finds it in _selectedItemRows and then unset it as it continues searching. Instead you want to replace this with something like the following:

cell.accessoryType = UITableViewCellAccessoryNone; 
for(NSIndexPath * elem in _selectedItemRows)
{ //Enumerate through checked cells  
    //NSIndexPath *ip = [_selectedItemRows objectAtIndex:x];  
    if ([indexPath compare:elem] == NSOrderedSame) { //If the current cell index path ='s any index path in the array of checked cells, check this cell.  
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
        break;
    }  
}  
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top