使用自定义子视图滚动 UITableView 时重复数据

Posted

技术标签:

【中文标题】使用自定义子视图滚动 UITableView 时重复数据【英文标题】:Duplicate data when scrolling a UITableView with custom subviews 【发布时间】:2013-08-22 11:35:24 【问题描述】:

这以前有效,除非它已经很长时间我忽略了一些东西。当表格第一次显示时,一切看起来都很棒,但是如果我上下滚动标签会得到重复的内容。

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

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

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

        UILabel *labelName = [[UILabel alloc] initWithFrame:CGRectMake(20, 0, tableView.frame.size.width, 35)];

        labelName.tag = 20;

        [cell addSubview:labelName];
    

    ((UILabel *)[tableView viewWithTag:20]).text = [data objectAtIndex:indexPath.row];

    return cell;

【问题讨论】:

试试 [cell.contentView addSubview:labelName]; 尝试将dequeueReusableCellWithIdentifier 设置为nil,从这个链接查看我的答案***.com/questions/15702242/… 不会将 dequeueReusableCellWithIdentifier 设置为 nil 为每一行创建一个新单元格? [cell.contentView addSubview:labelName];没有效果。 @RyanDetzel 是的,如果您的记录有限,则意味着不是一堆记录,否则请尝试我的以下回答:) 【参考方案1】:

我发现了引起它的那条线!

((UILabel *)[tableView viewWithTag:20]).text = [data objectAtIndex:indexPath.row];

您可以通过将-viewWithTag: 发送到tableView 来获得标签,但您应该询问该单元格。

附带说明,最好将子视图添加到单元格的contentView

这是正确的实现。

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

    static NSString *CellIdentifier = @"CellIdentifier";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (!cell)
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 
                                      reuseIdentifier:CellIdentifier];

        UILabel *labelName = [[UILabel alloc] initWithFrame:CGRectMake(20, 0, tableView.frame.size.width, 35)];

        labelName.tag = 20;

        [cell.contentView addSubview:labelName];
    

    ((UILabel *)[cell.contentView viewWithTag:20]).text = [data objectAtIndex:indexPath.row];

    return cell;

【讨论】:

该死的,不错的收获。我认为一切看起来都很好,有另一双眼睛很好。新行的单元格为零是否正常?我认为它会为每一行重复使用相同的单元格?例如,当 tableview 首次加载时,每个新行的单元格都是 nil。 是的,需要分配第一个单元格。只有在它们被滚动出来后,它们才能被重复使用。 参考您的帖子回答,我可以问一个与此cell.contentView相关的问题吗?【参考方案2】:

if (cell == nil) 条件内写下下面一行

labelName.text = [data objectAtIndex:indexPath.row];

并评论或删除此波纹管..

((UILabel *)[tableView viewWithTag:20]).text = [data objectAtIndex:indexPath.row];

【讨论】:

我知道,但如果记录不多,那么它将完全有效并且 "If" 即使他只有很少的数据,也会有很多人阅读这个解决方案,这不是如何使用表格视图的好例子。 现在您的编辑只会在第一次分配单元格时设置文本。他已经将文本设置在他应该做的地方! 这里的问题是文本被覆盖,所以当tableview重新加载时它再次调用时,这是避免它的方法,如果你知道最好的答案,那么请发布那个答案伙计..: ) 不,它不起作用,伙计,但我认为上述解决方案现在更好:)

以上是关于使用自定义子视图滚动 UITableView 时重复数据的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式加载自定义子视图,就像它们是单元格一样?

UIStackView 中等宽的自定义子视图

延迟加载 UICollectionViewCell 的自定义子视图

SwiftUI GeometryReader 不会在中心布局自定义子视图

IBOutlets/actions 和自定义子视图

iOS 视图上的自定义子视图有空插座