5

当我在“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--;
    }
}
}
4

3 回答 3

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;
}
于 2012-09-25T14:58:44.427 回答
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;
于 2011-03-20T18:50:46.530 回答
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,这样我就知道检查了哪些indexPaths。保留这样的数组可以让您轻松限制用户可以检查的单元格数量。这是我的 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];
}
于 2012-04-05T13:47:08.970 回答