UITableView 单元格在高度变化后显示错误的内容

UITableView cell displaying wrong content after height change

我正在努力实现一个包含三个部分的 UITableView。第二部分的最后一行应该显示 UIPicker 的实例。

因此,我更改了该特定行的高度,如下所示:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    CGFloat rowHeight = self.tableView.rowHeight;
    if (indexPath.section == RedZoneSection && indexPath.row == MonitorConfigRow){
        rowHeight = 162;
        return rowHeight;
    }
    return rowHeight;
}

但是,当我添加该代码时,第三部分的第一行 ("Only Alert From") 向它的视图添加了一个不应该存在的 UISwitch,如下所示:

下面是我为第三部分实现 cellForRowAtIndexPath 的地方:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForTimeOfDayRestrictionsRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"SettingsRowCell";

    UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
    }

    cell.backgroundColor = [UIColor colorWithRed:0.922 green:0.937 blue:0.949 alpha:1];

    switch (indexPath.row) {
        case HourTimeZoneRow:
            cell.textLabel.text = NSLocalizedString(@"Only Alert From", @"Only Alert Row");
            break;
        default:
            break;
    }
    return cell;
}

编辑 在错误位置再次显示的特定 UISwitch 最初位于我 table 第一节的第二个单元格中。下面是该部分的 cellForRowAtIndexPath 的实现:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForSubscribedNotificationsRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"SettingsRowCell";

    UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
    }

    cell.backgroundColor = [UIColor colorWithRed:0.922 green:0.937 blue:0.949 alpha:1];

    UISwitch *cellSwitch = nil;

    switch (indexPath.row) {
        case RowOne:
            cell.textLabel.text = NSLocalizedString(@"Row One", @"Row One");
            cellSwitch = [[UISwitch alloc] init];
            cell.accessoryView = cellSwitch;
            break;

        case RowTwo:
            cell.textLabel.text = NSLocalizedString(@"Row Two", @"Row Two");
                cell.accessoryView = cellSwitch;
                break;
 //            cell.textLabel.text = nil ;
            cell.accessoryView = UITableViewCellAccessoryNone;
            accessoryViewIsShowing = FALSE;
            break;
    }
    if (cell.accessoryView == nil) {
        NSLog(@"Cell accessoryView is nil");
    }
    else if (cell.accessoryView != nil){
        NSLog(@"Cell accessoryView is not nil");
    }

    NSLog(@"Section: %ld, Row: %ld", (long)indexPath.section, (long)indexPath.row);

    return cell;
}

有谁知道为什么更改特定单元格的高度会导致其他部分的单元格中显示不正确的内容?

问题是由于 tableView:cellForSubscribedNotificationsRowAtIndexPath: 方法中与回收单元相关的错误。更改其中一个单元格的高度会使此错误可见。

您需要将代码添加到 default 案例中,以删除您为 RowOneRowTwo 添加的附件和单元格文本:

default:
    cell.textLabel.text = nil;
    cell.accessoryView = nil;
    break;

否则,RowOneRowTwo 以外的行中的 "recycled" 单元格,曾经是 RowOneRowTwo,将包含旧的回收单元格之前存在的文本和附件视图。

解决此问题的另一种方法是 overriding prepareForReuse