iOS: CellForRowAtIndexPath cells are getting mixed up

前端 未结 3 1635
走了就别回头了
走了就别回头了 2021-01-06 02:53

Going to start off by saying I\'ve seen these questions:

iOS: UITableView mixes up data when scrolling too fast

(custom) UITableViewCell's mixing up afte

相关标签:
3条回答
  • 2021-01-06 03:08

    Adding an else solved my problem. Where I reseted any changes that were made to the cell.

    if (! self.cell) {
    
    self.cell = [[LanguageCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
    
    self.cell.accessoryType = UITableViewCellAccessoryNone;
    }
    else {
    self.cell.checkImage.image = NO;
    
    }
    
    0 讨论(0)
  • 2021-01-06 03:09

    There are a couple of ways to deal with this cell reuse problem (and that is what the problem is), and the way you're doing it now is ok. The problem is that when you scroll down and back up again, the cell that's returned for section 0 could be a cell that was previously used for section 1, so it will have any subviews you put in there.

    Another way to handle this, is to create two different prototype cells in the storyboard, and return the one with a simple label for section 0, and return the other one, with any subviews added in IB, for section 1. This way, you will always get the correct type of cell for each section without having to remove any subviews -- you only need to re-populate the cell with the correct data.

    0 讨论(0)
  • 2021-01-06 03:21

    So after a little bit of frustration, and careful analysis I found out why the cells were getting mixed up.

    My assumption about cell reuse (particularly with the identifiers) was the problem.

    Previously I was doing this:

    static NSString *CellIdentifier = @"Cell";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    }
    

    Which is great and all, however there is a critical problem. All cells were technically the same underneath... after they are all allocated (not nil) the system could not determine which cell to reuse no matter what section it was.

    This meant that any cell could be grabbed from the queue, with whatever it had in it, and stuck anywhere (despite my checks to make sure section 1 stuff went in section 1, and section 0 stuff (the fake renter) stayed in there).

    The solution:

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
    //Note: the if (cell == nil) thing is no longer required in iOS 6
    static NSString *CellIdentifier1 = @"Cell";
    static NSString *CellIdentifier2 = @"Cell2";
    
    UITableViewCell *cell;
    
    if (indexPath.section == 0)
    {
        if (cell == nil)
        {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier1];
        }
        else
        {
            cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier1];
        }
    
    }
    else
    {
        if (cell == nil)
        {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier1];
        }
        else
        {
            cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier2];
        }
    }
    
    
    if (closestRenter != nil)
    {
        NSLog(@"CLOSEST RENTER!");
        [self setupCellsWithClosestRenterCell:cell atIndexPath:indexPath];
    }
    else
    {
        NSLog(@"NO CLOSEST RENTER");
        [self setupCellsWithNoClosestRenterCell:cell atIndexPath:indexPath];
    }
    
    return cell;
    

    }

    As you can see, section 0 will get its own cell identifier. As will section 1. The result is that when a cell is to be dequeued, it will check which section the indexPath is currently at and grab the correct cell.

    Ugh, such a frustrating problem but now it all makes sense :)

    0 讨论(0)
提交回复
热议问题