UITableView didSelectRowAtIndexPath在点击时添加额外的复选标记

时间:2011-03-20 17:54:10

标签: iphone uitableview didselectrowatindexpath

当我在'didSelectRowAtIndexPath'中选择一个玩家并在所选行上添加一个复选标记时,它会添加一个额外的复选标记。

如果我点击row = 0,它会在row = 0和row = 11上添加一个复选标记。这意味着两行标记为一次。如果我点击row = 1,它会为row = 10添加一个额外的复选标记,因此它会向前添加10行复选标记。看起来它只是添加了复选标记,因为玩家没有进入实际的玩家列表。

非常感谢任何帮助。

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];

NSLog(@"indexPath: %i", indexPath.row);

// To many players selected
if (nrOfSelectedPlayers == 6) { //This is max players allowed
    UIAlertView *alertPlayer = [[UIAlertView alloc] initWithTitle:@"VARNING"
                                                          message:@"Du kan maximalt spela \n med sex spelare!" 
                                                         delegate:self 
                                                cancelButtonTitle:@"Tillbaka" 
                                                otherButtonTitles:nil];

    [alertPlayer show];
    [alertPlayer release];
    nrOfSelectedPlayers--;
    checkDeletePlayer = YES;
}
else { 

    // Handle the number of selected players to be able to delete player +6
    if (checkDeletePlayer == YES) {
        checkDeletePlayer = NO;
        nrOfSelectedPlayers++;
    }


    if (cell.accessoryType == UITableViewCellAccessoryNone) {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
        [selectedPlayersArray addObject:cell.textLabel.text];
        nrOfSelectedPlayers++;
    } 
    else {
        cell.accessoryType = UITableViewCellAccessoryNone;
        selectedPlayer = cell.textLabel.text;

        for (int oo = 0; oo < nrOfSelectedPlayers; oo++) {
            if ([selectedPlayersArray objectAtIndex:oo] == cell.textLabel.text) {
                [selectedPlayersArray removeObjectAtIndex:oo];
                nrOfSelectedPlayers--;
            }
        }
        //nrOfSelectedPlayers--;
    }
}
}

3 个答案:

答案 0 :(得分:7)

我使用动态原型单元格的故事板显示状态列表我在找到此解决方案之前使用了上述一些想法

第1步

@interface StateViewController : UITableViewController
{
    NSMutableArray *checkedIndexPaths;
}

第2步

(void)viewDidLoad
{
    [super viewDidLoad];
    self.states = [[GAIGStateStore sharedInstance]allStates];

    //Setup default array to keep track of the checkmarks
    checkedIndexPaths = [NSMutableArray arrayWithCapacity:self.states.count];
    for (int i = 0; i < self.states.count; i++) {
        [checkedIndexPaths addObject:[NSNumber numberWithBool:NO]];
    }
}

第3步

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

    //This toggles the checkmark
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];

    if (cell.accessoryType == UITableViewCellAccessoryNone)
    {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
        //This sets the array
        [checkedIndexPaths replaceObjectAtIndex:indexPath.row withObject:[NSNumber numberWithBool:YES]];

    } else
    {
        cell.accessoryType = UITableViewCellAccessoryNone;
         //This sets the array
        [checkedIndexPaths replaceObjectAtIndex:indexPath.row withObject:[NSNumber numberWithBool:NO]];

    }


}

第4步

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:stateCell forIndexPath:indexPath];

    UILabel *stateLabel = (UILabel *)[cell viewWithTag:1000];

    StateProvince *myState = [self.states objectAtIndex:indexPath.row];

    stateLabel.text = myState.label;

    //Now set the check marks
    // Assume cell not checked;
    [cell setAccessoryType:UITableViewCellAccessoryNone];

    NSNumber *num = [checkedIndexPaths objectAtIndex:indexPath.row];


    if (num == [NSNumber numberWithBool:YES]) {
           [cell setAccessoryType:UITableViewCellAccessoryCheckmark];
    }


    return cell;
}

答案 1 :(得分:6)

您遇到的问题是由细胞重复使用引起的。

基本上,如果您的UITableView有50个要显示的单元格,它只会创建10个,然后在向下滚动/向上滚动时重复使用它们。因此,无论您对第0行的单元格所做的任何更改,都将为第11行重新显示,因为TableView使用相同的单元格等。

您要做的是跟踪哪些玩家是独立于小区选择的。你可以通过创建一个集合轻松实现这一点,比如说NSMutableArray或NSMutableDictionary,它将把BOOL值存储在NSNumber对象中,例如。

NSMutableArray *players = [NSMutableArray arrayWithCapacity:50];
for (int i = 0; i < 50; i++) {
    [players addObject:[NSNumber numberWithBool:NO]];
}

然后在 didSelectRowAtIndexPath:(NSIndexPath *)indexPath 中,您只需更改相应NSNumber对象的值,而不是在单元格上操作。

然后在 cellForRowAtIndexPath:(NSIndexPath *)indexPath 中,通过检查播放器集合中的相应条目来配置单元附件。

或者,如果你真的非常顽固,你可以从 cellForRowAtIndexPath :( NSIndexPath *)indexPath 中替换(这不是推荐)以下一行:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

使用:

UITableViewCell *cell = nil;

答案 2 :(得分:2)

对于其他人来这里(就像我一样),看看为什么他们的表选择随机单元格,你必须在你的cellForRowAtIndexPath中添加如下内容:

// Assume cell not checked;
[cell setAccessoryType:UITableViewCellAccessoryNone];
for (int i = 0; i < checkedIndexPaths.count; i++) {
    NSUInteger num = [[checkedIndexPaths objectAtIndex:i] row];

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

我保留一个名为checkedIndexPaths的NSMutableArray,以便我知道检查了哪些indexPath。保留这样的阵列可以轻松限制用户可以检查的单元格数量。这是我的didSelectRowAtIndexPath的一个例子:

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

    // uncheck if already checked
    if (cell.accessoryType == UITableViewCellAccessoryCheckmark) {
        cell.accessoryType = UITableViewCellAccessoryNone;
        [checkedIndexPaths removeObject:indexPath];
    }
    else {
        // make sure no more than 3 are selected
        if ([checkedIndexPaths count] < 3) {

            // check row
            cell.accessoryType = UITableViewCellAccessoryCheckmark;
            // add it to our list of checked indexes
            [checkedIndexPaths addObject:indexPath];
        } else {
            UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Note" 
                                                            message:@"You can only select 3 rows." 
                                                           delegate:nil 
                                                  cancelButtonTitle:@"OK" otherButtonTitles:nil];
            [alert show];
        }
    }  
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
}