方法有问题:prepareForReuse

Having problems with the method: prepareForReuse

我有一个自定义 UITableViewCell,当它被 selected 时,它会扩展并向 selected 单元格 UIView 添加一个 UILabel我在故事板中添加了。

当我 运行 应用程序和 select 单元格时,标签会按预期添加到 myView。问题是,当我向下滚动时,标签也显示在另一个单元格中。

显然,它之所以如此,是因为我正在重复使用电池,但我没有像 Emilie 所说的那样清洁它们。我正在尝试调用 prepareForReuse 和 'cleaning' 单元格的方法,但我无法做到这一点。这是我的代码:

- (void)prepareForReuse {
    NSArray *viewsToRemove = [self.view subviews];
    for (UILablel *v in viewsToRemove) {
    [v removeFromSuperview];
}

这样做,甚至可以清除 selected 单元格标签。

- (void)viewDidLoad {
    self.sortedDictionary = [[NSArray alloc] initWithObjects:@"Californa", @"Alabama", @"Chicago", @"Texas", @"Colorado", @"New York", @"Philly", @"Utah", @"Nevadah", @"Oregon", @"Pensilvainia", @"South Dekoda", @"North Dekoda", @"Iowa", @"Misouri", @"New Mexico", @"Arizona", @"etc", nil];

    self.rowSelection = -1;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    CategorieCell *customCell = [tableView dequeueReusableCellWithIdentifier:@"cellID" forIndexPath:indexPath];
    customCell.title.text = [self.sortedDictionary objectAtIndex:indexPath.row];
    return customCell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    CategorieCell *customCell = (CategorieCell *)[tableView cellForRowAtIndexPath:indexPath];

    if (self.info) {
        [self.info removeFromSuperview];
    }

    self.info = [[UILabel alloc] init];
    [self.info setText:@"Hello"];
    [self.info setBackgroundColor:[UIColor brownColor]];

    CGRect labelFrame = CGRectMake(0, 0, 50, 100);
    [self.info setFrame:labelFrame];

    [customCell.infoView addSubview:self.info];

    NSLog(@"%ld", (long)indexPath.row);

    self.rowSelection = [indexPath row];
    [tableView beginUpdates];
    [tableView endUpdates];

}


- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ([indexPath row] == self.rowSelection) {
        return 159;
    }
    return 59;
}

答案很简单:你像你应该的那样重复使用你的细胞,但从不清洗它们

重用您的 UITableViewCell 意味着您之前单击的单元格在屏幕外时将被重用。

点击后,您会在 UITableViewCell 中添加一个视图。重用时,视图仍然存在,因为您永远不会删除它。

您有两个选择:一,您可以设置 self.info 视图的标签(或检查您保存在内存中的索引路径),然后检查您何时将单元格出列,如果信息视图在那里,然后将其删除。更简洁的解决方案是通过覆盖自定义 UITableViewCell

prepareForReuse 方法来实现视图删除

精度

您需要做的第一件事是在初始化后为您的 self.info 视图设置一个标签:

[self.info setTag:2222];

如果您想使其尽可能简单,您可以直接在 cellForRowAtIndexPath 方法中检查并删除 self.info 视图:

CategorieCell *customCell = [tableView dequeueReusableCellWithIdentifier:@"cellID" forIndexPath:indexPath];
customCell.title.text = [self.sortedDictionary objectAtIndex:indexPath.row];
if [customCell.infoView viewWithTag: 2222] != nil {
    [self.info removeFromSuperview]
} 
return customCell;

我不确定这段代码能否编译,我现在无法在我这边进行测试。希望有用!