UItableviewCell 单元格重用问题

Posted

技术标签:

【中文标题】UItableviewCell 单元格重用问题【英文标题】:UItableviewCell cell reuse issue 【发布时间】:2016-12-16 07:43:23 【问题描述】:

我在scrollview 中水平显示图像UItableviewCell

问题是当我滚动 tableview 时图像不匹配。以下是我的参考代码:

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


ManufacturersTableviewCustomCell * cell = (ManufacturersTableviewCustomCell *)[tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
if (cell == nil)

    cell = [[ManufacturersTableviewCustomCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];



cell.scrollview.delegate = self;
cell.backgroundColor = [UIColor clearColor];
cell.backgroundView = [UIView new] ;
cell.selectedBackgroundView = [UIView new] ;
cell.scrollview.tag = indexPath.row;
cell.btnViewAll.tag = indexPath.row;

NSDictionary *dict ;
NSArray *aryImages;


if(isFiltered && [aryFilteredProducts count]>0)
    dict = [[aryFilteredProducts objectAtIndex:indexPath.row]valueForKey:@"manufacturers"];
    aryImages = [[aryFilteredProducts objectAtIndex:indexPath.row]valueForKey:@"sub_categories"];

else if([aryProducts count]>0)
    dict = [[aryProducts objectAtIndex:indexPath.row]valueForKey:@"manufacturers"];
    aryImages = [[aryProducts objectAtIndex:indexPath.row]valueForKey:@"sub_categories"];



NSString *strUppercase = [[dict valueForKey:@"manufacturers_name"] uppercaseString];
cell.lblManufacturerName.text = strUppercase;

 NSString *strImgUrl = [NSString stringWithFormat:@"%@/%@",KServerUrl,[dict valueForKey:@"original_image"]];

if(![[NSURL URLWithString: strImgUrl] isKindOfClass:[NSNull class]])
    [cell.imgViewManufacturer setImageWithURL:[NSURL URLWithString:strImgUrl] placeholderImage:[UIImage imageNamed:@"Background.png"] usingActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];

[cell.viewBorder.layer setBorderColor: [[UIColor colorWithRed:234.0/255.0 green:234.0/255.0 blue:234.0/255.0 alpha:1.0] CGColor]];
[cell.viewBorder.layer setBorderWidth: 1.0];

[cell.imgViewManufacturer.layer setBorderColor: [[UIColor colorWithRed:234.0/255.0 green:234.0/255.0 blue:234.0/255.0 alpha:1.0] CGColor]];
[cell.imgViewManufacturer.layer setBorderWidth: 1.0];

CGFloat contentWidth = 0;

for(int i=0;i< [aryImages count];i++)

    if(SCREEN_MAX_LENGTH == 568)
        if([aryImages count] >3)
            cell.btnViewAll.hidden = NO;
        
        else  
            cell.btnViewAll.hidden = YES;
        
    
    else
        if([aryImages count] >5)
            cell.btnViewAll.hidden = NO;
        
        else  
            cell.btnViewAll.hidden = YES;
        
    
    NSDictionary *dictImageData = [aryImages objectAtIndex:i];

    UIImageView *imgView   = [[UIImageView alloc]initWithFrame:CGRectMake([aryImages indexOfObject:dictImageData]*(80 + 5),0,80,80)];

    if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad)
        [imgView setFrame:CGRectMake([aryImages indexOfObject:dictImageData]*(130 + 5),0,130,130)];
    
     [imgView.layer setBorderColor: [[UIColor colorWithRed:234.0/255.0 green:234.0/255.0 blue:234.0/255.0 alpha:1.0] CGColor]];
     [imgView.layer setBorderWidth: 1.0];
    imgView.tag  = i;
    // add tapgesture

    UITapGestureRecognizer *tapgestureImg = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(imageTapped:)];
    [imgView addGestureRecognizer:tapgestureImg];

    NSString *strImgUrlSubCat = [NSString stringWithFormat:@"%@/%@",KServerUrl,[dictImageData valueForKey:@"sub_product_img"]];

    imgView.userInteractionEnabled = NO;

    imgView.image = [UIImage imageNamed:@"Background.png"];

    if(![[NSURL URLWithString: strImgUrlSubCat] isKindOfClass:[NSNull class]])
        [imgView setImageWithURL:[NSURL URLWithString:strImgUrlSubCat ] placeholderImage:[UIImage imageNamed:@"Background.png"] usingActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
        imgView.userInteractionEnabled = YES;

    
    [cell.scrollview addSubview:imgView];

    UIView *vwBackGround = [[UIView alloc]initWithFrame:CGRectMake([aryImages indexOfObject:dictImageData]*(80 + 5), 60, 80, 20)];
    if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad)
        [vwBackGround setFrame:CGRectMake([aryImages indexOfObject:dictImageData]*(130 + 5), 90, 130, 40)];
    
    vwBackGround.backgroundColor = [UIColor blackColor];
    vwBackGround.alpha = 0.5;
    [cell.scrollview  addSubview:vwBackGround];

    UILabel *lblProductName = [[UILabel alloc]initWithFrame:CGRectMake([aryImages indexOfObject:dictImageData]*(80 + 5)+4, 60, 70, 20)];
    lblProductName.font = [UIFont fontWithName:@"Helvetica" size:10.0];

    if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad)
        [lblProductName setFrame:CGRectMake([aryImages indexOfObject:dictImageData]*(130 + 5)+4, 90, 120, 40)];
        lblProductName.font = [UIFont fontWithName:@"Helvetica" size:17.0];

    
    lblProductName.textColor = [UIColor whiteColor];
    lblProductName.text  = [dictImageData valueForKey:@"sub_product_name"];
    [cell.scrollview addSubview:lblProductName];

    [cell.scrollview bringSubviewToFront:vwBackGround];
    [cell.scrollview bringSubviewToFront:lblProductName];

    if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad)
        contentWidth += 130 + ([aryImages indexOfObject:dictImageData]==0?0:5);
    
    else
        contentWidth += 80 + ([aryImages indexOfObject:dictImageData]==0?0:5);

    



cell.scrollview.contentSize = CGSizeMake(contentWidth, cell.scrollview.frame.size.height);

return cell;

您能否建议如何解决此问题。

【问题讨论】:

细胞,如你所说,被重复使用。因此,您必须涵盖所有情况。你的代码没有。问问自己,如果图像视图已经添加到此单元格中,现在该单元格被重用并且您的代码运行,会发生什么。 如果您正在动态添加UIImages 并且不再使用它们,请在添加新图像之前清除重复使用的单元格内容。理解中的关键词UITableviewCellreused 我添加了这段代码 if ([cell.contentView subviews]) for (UIView *subview in [cell.contentView subviews]) if([subview isKindOfClass:[UIImageView class]]) [子视图 removeFromSuperview]; 但不工作。有什么可做的 @matt 谢谢你的建议。 【参考方案1】:

在添加之前删除图像视图..

通过在 cellforrowatindexpath 中添加以下代码解决了这个问题

   if ([cell.scrollview subviews])
    for (UIView *subview in [cell.scrollview subviews]) 
        if([subview isKindOfClass:[UIImageView class]] || [subview isKindOfClass:[UIView class]])
        [subview removeFromSuperview];
        
    

【讨论】:

以上是关于UItableviewCell 单元格重用问题的主要内容,如果未能解决你的问题,请参考以下文章

我的 UITableViewCell 正在重用以前的单元格 UIImage

UITableViewCell 布局在重用单元格之前不会更新

通过按钮、标签和单元格重用问题检查 uitableviewcell 中的图像无法正常工作

UITableViewCell 重用和图像重新渲染

无法从出列可重用 UITableViewCell 加载自定义单元格

如何在 Storyboard 控制器中重用定义为原型单元的自定义 UITableViewCell