【问题标题】:UITableView - When scrolling too fast, contents of last cell replaces first cellUITableView - 当滚动太快时,最后一个单元格的内容会替换第一个单元格
【发布时间】:2012-10-22 16:43:12
【问题描述】:

这可能是由于设计不佳造成的,但是当我滚动表格太快,然后滚动回顶部时,放置在最后一个表格单元格中的视图也会放在 tableView 中的第一个表格单元格上。

我认为这可能是由于我使用 if 语句将一些静态内容放在第一部分而将动态内容放在第二部分造成的。

感谢任何帮助。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    // Configure the cell...

    if (indexPath.section == 0) {

        if (indexPath.row == 0) {

            cell.selectionStyle = UITableViewCellSelectionStyleNone;
            UITextField *textField = [[UITextField alloc]initWithFrame:CGRectMake(10, 13, 282, 20)];
            textField.clearsOnBeginEditing = NO;
            textField.placeholder = @"enter template name";
            textField.font = [UIFont systemFontOfSize:15.0];
            textField.clearButtonMode = UITextFieldViewModeWhileEditing;
            textField.delegate = self;
            textField.text = [selectedTemplate name];
            [textField addTarget:self action:@selector(nameDidChange:) forControlEvents:UIControlEventEditingChanged];
            [cell.contentView addSubview:textField];

        } else {

            cell.textLabel.text =  @"Add a new question";
            cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

        }

    } else {

        NSString *label = [[sortedQuestions valueForKey:@"questionText"] objectAtIndex:indexPath.row];
        CGSize stringSize = [label sizeWithFont:[UIFont boldSystemFontOfSize:15] constrainedToSize:CGSizeMake(230, 9999) lineBreakMode:NSLineBreakByWordWrapping];

        UITextView *textV=[[UITextView alloc] initWithFrame:CGRectMake(5, 5, 230, stringSize.height+10)];
        textV.font = [UIFont systemFontOfSize:15.0];
        textV.text=label;
        textV.textColor=[UIColor blackColor];
        textV.editable = NO;
        textV.userInteractionEnabled = NO;
        textV.backgroundColor = [UIColor colorWithRed:0.97f green:0.97f blue:0.97f alpha:1.00f];
        [cell.contentView addSubview:textV];

        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

    }

    return cell;
}

【问题讨论】:

    标签: objective-c ios uitableview


    【解决方案1】:

    我知道这已经有一个公认的答案,但我想我会更深入地了解发生这种情况的“原因”以及解决方案。

    用外行的话来说,UITableView 的刷新速度落后于所要求的演示速度。换句话说,由于快速滚动,预计表格视图重新填充内容的速度要快于对预期单元格进行排序以重用于其各自的索引(行)的速度。

    Wienke 提到的最简单的解决方案是为第一个单元格创建不同 单元格标识符,比如说三 (3) 个单元格。这将使表格视图能够清楚地区分 3 个单元格,防止任何单元格错位。

    也许这里最好的方法是为每个单元分配相关的单元标识符(取决于上下文和单元的数量)。通过这种方式,表格视图可以准确地知道哪个单元格(带有各自的 ID)去哪里。如下所示:

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
        NSString *cellID = [NSString stringWithFormat:@"cell%lu", indexPath.row];
        __kindof UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
    
        if (!cell) {
    
            // Create your cell here.
            cell = [...allocate a new cell...] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
    
        }
    
        return cell;
    
    }
    

    【讨论】:

      【解决方案2】:

      这是我根据 Wienke 的建议最终做的事情。我在情节提要中添加了 3 个原型单元,名为 Cell,Cell2,Cell3。

      相关代码:

      static NSString *CellIdentifier = @"Cell";
      static NSString *CellIdentifier2 = @"Cell2";
      static NSString *CellIdentifier3 = @"Cell3";
      
      UITableViewCell *cell;
      
      if (indexPath.section == 0 && indexPath.row == 0) {
      
          cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
      
      } else if (indexPath.section == 0 && indexPath.row == 1) {
      
          cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier2 forIndexPath:indexPath];
      
      } else if (indexPath.section == 1) {
      
          cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier3 forIndexPath:indexPath];
      
      }
      

      我还添加了这个来检查我的动态单元格,并在添加新子视图之前删除任何可能存在的挥之不去的子视图。

          if ([cell.contentView subviews]){
              for (UIView *subview in [cell.contentView subviews]) {
                  [subview removeFromSuperview];
              }
          }
      

      【讨论】:

        【解决方案3】:

        它看起来像是为第 0 行第 0 行布置的单元格正在出列并用于例如第 0 行第 1 行,这并没有替换为它所做的所有设置持有section 0 row 0材料。

        您可能需要考虑使用 3 个单独的单元格标识符,一个用于第 0 行的第 0 行,一个用于第 0 行的第 1 行,一个用于所有其余的。您需要一组初步的 if 语句(或 switch-case 语句),以便在调用 dequeueReusableCellWithIdentifier: 时使用正确的标识符。

        【讨论】:

        • 谢谢,这似乎成功了。你能告诉我这是否是完成我在这里尝试做的事情的典型方式,还是我的方法偏离了轨道?我将在我的代码中添加一个答案以供将来参考。
        • 很高兴它成功了。我不知道什么是典型的,但我认为如果它涵盖了 0 以外的所有部分,你会从“Cell3”中获得一些里程。标识符和出队的想法是通过不必重建新的来提高性能每次将不同的项目滚动到视图中时,单元格。通过查看此处与 UITableView 相关的许多帖子,您可能会更好地了解规范;他们总是有助于理解官方文档。祝你好运!
        猜你喜欢
        • 1970-01-01
        • 2019-12-21
        • 1970-01-01
        • 2017-02-02
        • 2012-08-09
        • 1970-01-01
        • 2012-02-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多