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

发布于 2024-10-24 00:30:12 字数 1939 浏览 1 评论 0原文

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

When i select a player in 'didSelectRowAtIndexPath' and add a checkmark on the selected row it adds an additional checkmark.

If i tap row = 0 it adds a checkmark to row = 0 and row = 11. This means that two row's are marked by one tap. If i tap row = 1 it adds an extra checkmark to row = 10 so it adds checkmark 10 rows forward. It seems like it only add the checkmark as the player does not get into the actual player-list.

Any help would be very much appreciated.

- (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--;
    }
}
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

携君以终年 2024-10-31 00:30:12

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

步骤 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;
}

I am using storyboards with Dynamic Prototype Cells to display a list of states I used some of the ideas above before I found this solution

Step 1

@interface StateViewController : UITableViewController
{
    NSMutableArray *checkedIndexPaths;
}

Step 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]];
    }
}

Step 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]];

    }


}

Step 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;
}
折戟 2024-10-31 00:30:12

您面临的问题是由细胞重复使用引起的。

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

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

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;

The problem you are facing is caused by cell reusing.

Basically, if your UITableView has, let say 50 cells to display, it creates only 10 and then reuse them as you scroll down / scroll up. So whatever changes you did to the cell at row 0, it will be re-displayed for the row 11 as TableView uses the same cell etc.

What you want to do is to keep track of which players have been selected independently from cell. You can achieve that easily by creating a collection, let say NSMutableArray or NSMutableDictionary, which will store BOOL values in NSNumber objects, eg.

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

Then in didSelectRowAtIndexPath:(NSIndexPath *)indexPath you do instead of operating on cell, you will simply change the value of a corresponding NSNumber object.

Then in cellForRowAtIndexPath:(NSIndexPath *)indexPath you configure cell accessory by checking the corresponding entry in players collection.

Or if you are really, really stubborn you could replace (THIS IS NOT RECOMENDED) the following line from the cellForRowAtIndexPath:(NSIndexPath *)indexPath:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

with:

UITableViewCell *cell = nil;
久光 2024-10-31 00:30:12

对于其他来到这里的人(像我一样)要了解为什么他们的表选择随机单元格,您必须在 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];
}

For others coming here (like I did) to see why their table selects random cells, you have to add something like the following to your 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];
    }
}

I keep a NSMutableArray called checkedIndexPaths so that I know which indexPaths are checked. Keeping such an array allows you to easily limit the number of cells a user can check. Here's an example of my 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];
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文