UITableViewCell reusability issue. Modifying one c

2019-09-13 10:24发布

问题:

Whenever a cell from section 3 is selected. I'm updating the DataSource array, and the cell's background color is thus changing correctly.

However, whenever I scroll back up I start seeing random cells with the modified background color, knowing that I don't even mention it in my cellForRowAtIndexPath method and each section in my tableView is populated from a separate DataSource Array/Dictionary!

(I'm using a Storyboard to handle all UI setup)

Here's my code (focus on Section 3)

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

ECTextFieldTableViewCell *cell  = [tableView dequeueReusableCellWithIdentifier:kSettingsTextFieldCellReuseIdentifier
                                                                  forIndexPath:indexPath];

if (indexPath.section == 0) {

    cell.cellTextField.text = [self.personalInfoDataSource valueForKey:kUserValuesKey][indexPath.row];

 } else if (indexPath.section == 1) {

     cell.cellTextField.text = [self.contactInfoDataSource valueForKey:kUserValuesKey][indexPath.row];

 } else if (indexPath.section == 2) {

     cell.cellTextField.text = [self.professionalDetailsDataSource valueForKey:kUserValuesKey][indexPath.row];

 } else if (indexPath.section == 3) { //---- Problems here 

     UserMeta *metaObj = self.interestDataSource[indexPath.row];

     cell.cellTextField.userInteractionEnabled = NO;
     cell.cellTextField.text = metaObj;

     if (self.user.INTEREST.count > 0 && [self.user.INTEREST contains:metaObj.name] ) {
         cell.backgroundColor = [UIColor redColor];
     }         
 }

 return cell;
}

And here's where I'm doing all the DataSource modifications

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

if (indexPath.section == 0 && indexPath.row == 2) {

    // Do Stuff

} else if (indexPath.section == 3) { //---- Problems here 

    ECTextFieldTableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];

    cell.backgroundColor = [UIColor redColor];

    UserMeta *metaObj = self.interestDataSource[indexPath.row];
    [self.user.INTEREST addObject:metaObj];

} 

}

回答1:

As you wrote, cells are reused. A cell which was displayed in section 3 could be reused in section 0.

Therefore you have to make sure that all parameters are set to a defined state.

That means if you set userInteractionEnabled to NO and the background color depending on a condition to red in section 3 you have to set userInteractionEnabled to YES and the color to the default color in all other sections. Further you have to set the color to the default color in section 3 if the condition is false.



回答2:

Because table cells get reused when you scroll, you can't make any assumptions about its initial state. In cellForRowAtIndexPath you need to set the background color under all conditions, not just under a limited set of conditions. For example, you could set the background color to white just after dequeueing the cell, then set it to red lower down in one branch of the if statement.