iOS: CellForRowAtIndexPath cells are getting mixed up

前端 未结 3 1637
走了就别回头了
走了就别回头了 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: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 :)

提交回复
热议问题