重复的 UItableViewCell,UITableView 的行

Posted

技术标签:

【中文标题】重复的 UItableViewCell,UITableView 的行【英文标题】:Duplicate UItableViewCell, Rows of UITableView 【发布时间】:2013-01-11 13:30:21 【问题描述】:

在上下滚动 2 3 次后,此处的 tableview 将图像添加到所有单元格。代码如下:

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

HomeCell *cell = (HomeCell *) [tableView dequeueReusableCellWithIdentifier:@"HomeCell"];
if (cell == nil) 
    cell = [[HomeCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"HomeCell"] ;


VenueDC *venueObj = [subSubCategoriesArray objectAtIndex:indexPath.row];
cell.lblName.text = venueObj.name;
if ([venueObj.imagesArray count] > 0) 
    [cell.ivVenue setImage:venueObj.ivVenue];
    [cell.ivVenue setHidden:NO];
    cell.lblName.frame = CGRectMake(80, cell.lblName.frame.origin.y, 200, cell.lblName.frame.size.height);

venueObj = nil;


return  cell;

知道这里发生了什么吗?

图像仅在一个对象中,第一次加载时它会显示一个带有图像的单元格,但滚动后它也会开始在另一个单元格上显示图像。

【问题讨论】:

试试这个线程的答案,可能会对你有所帮助。 :***.com/questions/10535637/… 【参考方案1】:

这样解决了,首先我将 lblName 框架设置为其原始位置,因此每次使用单元格时都会重置其位置

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

HomeCell *cell = (HomeCell *) [tableView dequeueReusableCellWithIdentifier:@"HomeCell"];

if (cell == nil) 

    NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"HomeCell" owner:self options:nil];

    for (id currentObject in topLevelObjects)
        if ([currentObject isKindOfClass:[UITableViewCell class]])
            cell =  (HomeCell *) currentObject;
            break;
        
    


VenueDC *venueObj = nil;
venueObj = [subSubCategoriesArray objectAtIndex:indexPath.row];
cell.lblName.text = venueObj.name;
[cell.ivVenue setHidden:YES];
cell.lblName.frame = CGRectMake(20 , 19, 250, 20);
if (venueObj.ivVenue) 
    [cell.ivVenue setImage:venueObj.ivVenue];
    [cell.ivVenue setHidden:NO];
    cell.lblName.frame = CGRectMake(80, cell.lblName.frame.origin.y, 200, cell.lblName.frame.size.height);
 
return  cell;

【讨论】:

【参考方案2】:

UITableViewCells 被重用,这就是 dequeueReusableCellWithIdentifier: 方法所做的。为了节省内存,UITableView 仅实例化在任何给定点上尽可能多的单元格,然后继续重复使用它们。因此,您应该始终在重用之前清理单元格,即将其所有内容重置为nil

如果您使用的是自定义表格视图,例如 HomeCell,则覆盖 -(void)prepareForReuse 并将图像设置为 nil。

【讨论】:

【参考方案3】:

发生这种情况是因为您的单元格被重复使用,因此请编写以下代码:

HomeCell *cell = (HomeCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) 
        
        NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"HomeCell" owner:self options:nil];
        
        for (id currentObject in topLevelObjects)
            if ([currentObject isKindOfClass:[UITableViewCell class]])
                cell =  (HomeCell *) currentObject;
                break;
            
        
    

【讨论】:

你的回答帮助我投票,但我解决的问题看我的回答【参考方案4】:

你只需要在cellForRowAtIndexPath中添加一行

NSString *CellIdentifier = [NSString stringWithFormat:@"S%1dR%1d",indexPath.section,indexPath.row];

然后改变

HomeCell *cell = (HomeCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

【讨论】:

这会有内存问题。你怎么看?它不会将任何单元格与另一个单元格重用,但在同一部分中具有相同的索引路径,从而导致创建的单元格数量与表格视图中存在的行数一样多。如果我错了,请纠正我。 是的,你写..在这段代码中,当用户滚动表格视图不重用旧单元格时,它会创建新单元格;) 有必要吗??我们可以通过重用单元格来创建相同的效果,从而减少内存使用量,然后这段代码将占用.. 但在某些情况下它是有帮助的。我知道cellForRowAtIndexPath 只调用可见单元格.. 它不调用不可见单元格...当用户滚动并显示单元格时,它不会创建新的(单元格)而是重用它:) dequeueReusableCellWithIdentifier:CellIdentifier 仅当 cellIdentifier 相同时才有效。但在您的情况下,它对于每个单元格都是唯一的。只有遇到相同的 cellIdentifier 才会重用。即,如果用户滚动到最后,然后再次滚动到顶部。第一个单元将仅与先前创建的第一个单元一起重用。这是没有意义的。取一个像 25 个元素这样的大数组,然后检查创建了多少单元格。如果用户滚动到 tableview 的最后一个,它将正好是 25。【参考方案5】:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

HomeCell *cell = (HomeCell *) [tableView dequeueReusableCellWithIdentifier:@"HomeCell"];
if (cell == nil) 
    cell = [[HomeCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"HomeCell"] ;


VenueDC *venueObj = [subSubCategoriesArray objectAtIndex:indexPath.row];
cell.lblName.text = venueObj.name;
    [cell.ivVenue setImage:nil];

if ([venueObj.imagesArray count] > 0) 
    [cell.ivVenue setImage:venueObj.ivVenue];
    [cell.ivVenue setHidden:NO];
    cell.lblName.frame = CGRectMake(80, cell.lblName.frame.origin.y, 200, cell.lblName.frame.size.height);

venueObj = nil;


return  cell;

【讨论】:

现在它没有显示图像但是,你可以看到这个图像被隐藏了,所以它确实进入了“If”并将 lblName 向前移动 检查图像是否存在..如果没有则不要设置 lblname 的框架。希望有帮助【参考方案6】:

您需要else 声明:

else 
venueObj = nil;

【讨论】:

以上是关于重复的 UItableViewCell,UITableView 的行的主要内容,如果未能解决你的问题,请参考以下文章

如何在 UITableViewCell 上使用 CAGradientLayers

uitableviewcell 中的自动布局问题

如何在 UITableViewCell 中添加多行文本字段?

当附件是UITableViewCellAccessoryCheckmark时,如何将文本置于UITableViewCell中

自定义 UITableViewCell 创建了两次......让我发疯

UITableViewCell 使用 separatorInset 隐藏分隔符在 iOS 11 中失败