UITableViewCell在dequeue上重绘

时间:2015-05-06 04:10:30

标签: ios objective-c uitableview uistoryboard tableviewcell

我的设置

我在UITableViewCell的主要故事板中有一个UITableViewController。它将填充从REST API中提取的一些JSON数据,这将导致每个单元格变为高度可变。有UIImageViewsUILabels所有不同的高度和风格,想想Instagram风格。

我的问题

当我滚动到第5或第6个单元格时,然后返回,它们开始重绘和重叠,因此文本混合,行重新绘制等等。

我尝试了什么

这似乎是SO上的一个常见问题,所以我尝试了几个已发布的解决方案。似乎我的问题可能与其他人面临的问题相同,也就是说,每次出列时我都在我的单元格上调用addSubview,但我已经尝试检查单元格是否已经存在。我在某处发现了另一篇文章(对不起,我记不起来了),这表明因为我在故事板中创建了它,它已经初始化并且if ( !cell )已经返回false,所以我不知道如何防止重绘。

当我尝试从故事板中删除单元格并以编程方式创建它时,我收到一条错误消息,指出它无法找到标识为@"Cell"的单元格。

当我出队时,我也尝试过某人删除所有子视图的解决方案,所以我使用了:

for ( UIView *view in cell.contentView.subviews ) {
     if ([view isKindOfClass:[UIView class]]) {
         [view removeFromSuperview];
     }
}

它找不到任何东西。

4 个答案:

答案 0 :(得分:2)

@ rdelmar的评论是正确的。你不应该做你正在做的事情。可能会工作,但形状不好,你不想养成坏习惯。

首先,利用面向对象的编程。单元格应该能够根据您要求它显示的数据进行自我配置。表格视图不应该设计单元格。

UITableViewCells需要针对速度进行优化。创建和添加子视图是一个缓慢的过程。可以执行一次,但是单元格将被重用(系统优化),您应该只重复使用第一次创建单元格时添加的现有视图。

例如,如果不需要子视图,则可以隐藏子视图。您可能希望在-prepareForReuse中执行此操作。你可以在-layoutSubviews中移动它们。或者在-updateConstraints中更改子视图的位置。

通常,您只想将数据传递给数据源(通常是视图控制器)的表视图单元子类。让单元格进行显示工作。

答案 1 :(得分:0)

尝试在单元类中将新方法添加到重置单元格为其默认样式,并在{{1}后调用此方法}。

答案 2 :(得分:0)

在您的单元格出列后添加子视图时,请为子视图添加标记。这样,当您将单元格出列时,您可以先检查标记是否存在子视图,如果存在,则在添加新视图之前将其删除:

- (UITableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    ...
    // try to dequeue a cell
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:<yourCellIdentifier>];

    if( !cell )
    {
        // create a new cell if necessary
    }

    static int _myViewTag = 1000987 // give it a high int : low value are used by the system in cells

    UIView *v = cell.contentView viewWithTag:_myViewTag];

    if( v ) // subview with such tag already exists, so remove it.
        [v removeFromSuperview];

    // now add your new subview
    [cell.contentView addSubview:<yourView>];

    // adjust height of cell to your view.
    ...
}

答案 3 :(得分:0)

管理此方法的最有效方法是将UITableViewCell子类化,并将所有必需的Views添加为属性。所以,现在当一个小区出现&#34; recycle&#34;时,您知道在哪里可以找到旧视图,例如:

[cell.myTextLabel setText:@""];

aaaand你已经完成了。

UPDATE 创建子类是有意义的,如果你只有少量的&#34; TYPES&#34;细胞为每个创建一个子类。它的复杂程度取决于您的具体情况。但我已经做到了,并发现它是最有效的方法。

UPDATE 2 或者您可以在故事板中创建多个单元格,并根据数据源将相应的单元格出列,保存所有编码。