iosobjective-cuitableviewaccessoryview

Wacky UITableViewCellAccessoryCheckmark Behavior


I am setting the UITableViewCellAccessoryCheckmark programmatically as seen in the code below. Sometimes it works perfectly and the cells that contain titles that should be checked are checked and the ones that shouldn't be checked aren't checked. BUT AT OTHER TIMES when a cell receives a check, the tableview will add a random checkmark to another cell that shouldn't be checked. But this occurs only on some lists even though it might contain the same exact data as another list that works fine. The cells are contained in a section that has a max of maybe 6 rows so they all appear on the screen once you scroll to that section. Most of the time the section only has 3 rows. If the checkmarks are screwed up because of reusing cells then I would think the section that has 6 rows would be the ones causing problems, but it's not. The messed up sections are the ones with only 3 rows! As you will see, I've logged just about every line and the debugger gives me what I expect to see but the tableview just goes and adds extra checkmarks that don't show up in the debugger. I just cannot figure out what I'm doing wrong. If anyone can just give me a jumping off point of what else to check, I'm all ears. Right now I'm all tears! Let me know if you need any other bits of code. Thanks in advance!

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{

if (indexPath.section == 0 && indexPath.row == 0)
{
    [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
}

if(_book.hasNovellaArray)
{
    NSMutableArray *storyList = [[NSMutableArray alloc] init];
    NSMutableArray *newList = [[NSMutableArray alloc] init];

    for (id title in _book.novellaArray)
    {
        [storyList addObject:title];
        NSLog(@"added title in the collection:%@:",storyList);
    }

    for (id story in _book.novellaRead)
    {
        [newList addObject:story];
        NSLog(@"added story has been read:%@:", newList);
    }

    for (id i in storyList)
    {
        for (id j in newList)
        {
            if ([ i isEqualToString:j])
            {
                NSLog(@"%@ = %@", i, j);
                if ([_detailCell.detailLabel.text isEqualToString:i])
                {
                    _detailCell.accessoryType = UITableViewCellAccessoryCheckmark;
                    NSLog(@"cells have been checked");
                    NSLog(@"title checked: %@", _detailCell.detailLabel.text);
                    NSLog(@"at index path %ld", (long)indexPath.row);
                }
            }
        }
    }
}

}


Solution

  • Cells get reused. When you conditionally set a property of a cell, you must always reset that property for all other conditions.

    -(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
        if (indexPath.section == 0 && indexPath.row == 0) {
            [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
        } else {
            [cell setSelectionStyle:UITableViewCellSelectionStyleDefault];
        }
    
        _detailCell.accessoryType = UITableViewCellAccessoryNone;
    
        if (_book.hasNovellaArray)
        {
            NSMutableArray *storyList = [[NSMutableArray alloc] init];
            NSMutableArray *newList = [[NSMutableArray alloc] init];
    
            for (id title in _book.novellaArray)
            {
                [storyList addObject:title];
                NSLog(@"added title in the collection:%@:",storyList);
            }
    
            for (id story in _book.novellaRead)
            {
                [newList addObject:story];
                NSLog(@"added story has been read:%@:", newList);
            }
    
            for (id i in storyList)
            {
                for (id j in newList)
                {
                    if ([ i isEqualToString:j])
                    {
                        NSLog(@"%@ = %@", i, j);
                        if ([_detailCell.detailLabel.text isEqualToString:i])
                        {
                            _detailCell.accessoryType = UITableViewCellAccessoryCheckmark;
                            NSLog(@"cells have been checked");
                            NSLog(@"title checked: %@", _detailCell.detailLabel.text);
                            NSLog(@"at index path %ld", (long)indexPath.row);
                        }
                    }
                }
            }
        }
    }