【问题标题】:Duplicate UItableViewCell, Rows of UITableView重复的 UItableViewCell,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;
}

知道这里发生了什么吗?

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

【问题讨论】:

标签: iphone ios uitableview


【解决方案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;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-13
        相关资源
        最近更新 更多