UITableViewCell重复问题

时间:2010-06-17 12:19:35

标签: iphone objective-c uitableview

我有一个带有单元格的UItableview。有些细胞有uilabels,有些有uibuttons。只要数组中的第一个字符为“^”,就会创建UI按钮。然而,当我向下滚动(出现在uilabel上方)时,uibuttons重复...然后当我向上滚动时,在uilabels上相乘。任何线索为什么?

4 个答案:

答案 0 :(得分:5)

每次滚动部分并加载行时,所有标签和ui组件都会在运行时添加到单元格中,每当单元格出列时,您需要清除单元格中添加的所有视图并且不是零,请参见以下示例:

    static NSString *CellIdentifier;

    CellIdentifier = [NSString stringWithFormat:@"Cell%d%d",indexPath.section,indexPath.row];

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
/*
 *  THIS IS FOR OS VERSION 2.2 THE OLDER VERSION
 *        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
 */

    } else {
        for (UIView* tempView in cell.contentView.subviews) {
            [tempView removeFromSuperview];
        }
    }

答案 1 :(得分:2)

不应在if (cell == nil)内设置单元格的内容。只应定义结构(布局)。检查后应设置内容:

CellIdentifier = @"TableCell";

cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];

        // setup everything that's the same for every cell
        // (e.g. add controls to the cell)
}

// setup everything that's different in each cell (set text, images, ...)

这里发生的是单元格正在“准备”并缓存,因此不必为每个单元格重新创建单元格。如果在if (cell == nil)内设置单元格的内容,则将单元格的内容存储在缓存中。

答案 2 :(得分:2)

UITableView不会为每个逻辑行保留一个UITableViewCell。它仅保留显示当前屏幕上的行所需的单元数。实际上,这意味着任何时候只存在9-11个默认高度单元格。

表视图通过调用表视图的数据源并为该行请求新单元或重用现有单元来创建任意长表的错觉。这种重用被称为“出列”单元。滚动浏览初始显示的行后,您不再创建新的单元格实例,而是一遍又一遍地使用相同的实例。

您的问题出现了,因为一旦您将单元格设置为具有UIButton,您就不会随后删除该按钮。一旦单元格中有一个按钮,它将永远显示该按钮,即使它用于显示不应该有按钮的逻辑行。因为反复使用相同的单元格来显示不同的行,所以快速滚动会使所有单元格显示按钮。

要解决您的问题,您需要在要显示标签时删除按钮,并在要显示按钮时删除标签。

更好的是,您应该定义UITableViewCell的两个子类,每个显示一个。如果你有一个带按钮的行返回按钮子类单元格,当你有一个带有标签的行返回标签子类时。这样,您可以将所有单元配置逻辑移动到单元类,并仅在数据源方法中设置数据。使用子类来封装自定义逻辑会产生更简洁,更清晰的代码,更易于调试和维护。

答案 3 :(得分:1)

您正在使用可重复使用的单元格,因此在cellForRowAtIndexPath中:您必须检查 - 单元格中是否有按钮或标签?如果是这样,删除它们,alloc-init一个新的并将其添加为子视图。为此,使用标签,非常舒适。