开发者

UITableView Multiple Checkmark Selection

Having read a couple of the questions asked relating to this, I can get the functionality to work. However my list is long and scrollable, so when I scroll up and down the selection of the checkmarks are all over the place. selectedIndexes is a NSMutableArray. Any ideas?

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];

    if ([selectedCell accessoryType] == UITableViewCellAccessoryNone) {
        [selectedCell setAccessoryType:UITableViewCellAccessoryCheckmark];
        [selectedIndexes addObject:[NSNumber numberWithInt:indexPath.row]];

    } 
    else {
        [selectedCell setAccessoryType:UITableViewCellAccessoryNone];
        [selectedIndexes removeObject:[NSNumber numberWithInt:indexPath.row]];

    }

    [tableView deselectRowAtIndexPath:indexPath animated:NO];

}

In my cellForRowAtIndexPath: i have the following check.

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

    static NSString *CellIdentifier = @"CustomCell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    // Configure the cell...
    NSDictionary *dictionary = [natures objectAtIndex:indexPath.section];
    NSArray *array = [dictionary objectForKey:@"Name"];
    NSString *cellValue = [array objectAtIndex:indexPath.row];
    cell.textLabel.text = cellValue;

    for (int i = 0; i < selectedIndexes.count; i++) {
        NSUIn开发者_运维问答teger num = [[selectedIndexes objectAtIndex:i] intValue];

        if (num == indexPath.row) {
            [cell setAccessoryType:UITableViewCellAccessoryCheckmark];
        }
        else {
            [cell setAccessoryType:UITableViewCellAccessoryNone];
        }

    }

    return cell;
}


For multiple selection you just need on viewDidLoad

self.tableView.allowsMultipleSelection = YES;

and

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *tableViewCell = [tableView cellForRowAtIndexPath:indexPath];
    tableViewCell.accessoryView.hidden = NO; 
    // if you don't use a custom image then tableViewCell.accessoryType = UITableViewCellAccessoryCheckmark;
}

- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *tableViewCell = [tableView cellForRowAtIndexPath:indexPath];
    tableViewCell.accessoryView.hidden = YES;
    // if you don't use a custom image then tableViewCell.accessoryType = UITableViewCellAccessoryNone;
}


You need to modify your cellForRowAtIndexPath to be the following:

// Assume cell is not checked -- if it is the loop below will check it.
[cell setAccessoryType:UITableViewCellAccessoryNone];
for (int i = 0; i < selectedIndexes.count; i++) {
        NSUInteger num = [[selectedIndexes objectAtIndex:i] intValue];

        if (num == indexPath.row) {
            [cell setAccessoryType:UITableViewCellAccessoryCheckmark];
            // Once we find a match there is no point continuing the loop
            break;
        }
    }

You need to do this because a reusable cell might have the checkmark set -- so you need to clear it. Hope this helps.

Incidentally, using an NSSet would probably be a more elegant solution!


No need to maintain separate array for storing selected rows. Use native method indexPathsForSelectedRows to get selected cells indexPath array. And just check arrayContains current IndexPath in cellForRow method as given below:

NSArray *indexPaths = [tableView indexPathsForSelectedRows];

if ([indexPaths containsObject:indexPath]) {
    cell.accessoryType = UITableViewCellAccessoryCheckmark;
}else {
    cell.accessoryType = UITableViewCellAccessoryNone;
}

#pragma mark- select/deselect 

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    [[self.tableView cellForRowAtIndexPath:indexPath] setAccessoryType:UITableViewCellAccessoryCheckmark];
}

-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {
    [[self.tableView cellForRowAtIndexPath:indexPath] setAccessoryType:UITableViewCellAccessoryNone];
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜