【问题标题】:How do I tell my UITableViewCell to "auto-resize" when its content changes?我如何告诉我的 UITableViewCell 在其内容更改时“自动调整大小”?
【发布时间】:2016-06-28 18:39:32
【问题描述】:

在我的 cell.xib 中,我有一个标签,它的所有方面都有约束。我已将该标签设置为lines = 0 和line-break = word wrap。然后,我对我的 TableView 执行此操作:

self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.estimatedRowHeight = 100.0

一切都很好,我的 UITableViewCell 是自动高度的。如果文字很长,那么我的tableView会智能计算大小。

问题是——一旦单元格中的内容发生变化,我如何告诉我的 UITableView “重新计算”大小?

我的单元格可以调用它的委托,在这个委托中,我希望 TableView 重新绘制高度。

现在,我的单元格中的内容不断变化,但单元格高度从未改变。

【问题讨论】:

  • 如果你的 UITableview 没有用UITableViewAutomaticDimension 调整大小,那么它的约束有问题。还有另一种自动调整大小的方法,我建议 yopu 使用 KeyValue Observer。
  • 你的意思是你的tableview高度会随着单元格的高度而变化吗?问题是单元格高度在变化,但表格视图高度没有变化?
  • 可以放截图吗?还有你想增加UITableViewCell或UITableView的高度吗?另外,你可以在哪个 iOS 版本上运行?
  • 另外,为什么你不使用 Prototype UITableViewCell?
  • TIMEX,没有回应任何人,他可能只是想获得所有可能的方法。下面的所有答案都应该满足这个问题,除了下面的答案之外,没有什么神奇的方法可以做到这一点。

标签: ios swift


【解决方案1】:

我认为最简单的解决方案是重新加载该特定单元格。例如:

- (void)yourDelegateMethodOfCell:(UITableViewCell *)cell {
    NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
    //If cell is not visible then indexPath will be nil so,
    if (indexPath) {
        [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
    }
}

【讨论】:

    【解决方案2】:

    我发现让它检查高度的最佳方法是在进行任何文本更改后按顺序调用:

    self.tableView.beginUpdates()
    self.tableView.endUpdates()
    

    这会导致 tableView 检查所有可见单元格的高度,并根据需要进行更改。

    【讨论】:

      【解决方案3】:

      您可以通过仅实现以下方法来调整单元格高度

       - (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath{
      return UITableViewAutomaticDimension;
      }
      

      【讨论】:

      • 这相当于self.tableView.rowHeight = UITableViewAutomaticDimension
      • 这仅在单元初始化期间有效。一旦它出队并更新数据,它就不会调整大小。
      【解决方案4】:

      我明白你的意思,我之前遇到过这个问题。
      您的单元格在 AutoLayout 中,并且您希望单元格自行更改。这里推荐答案:Using Auto Layout in UITableView for dynamic cell layouts & variable row heights,所以我们不再讨论这个问题。

      所以我们在这里专注于您的问题。

      由于您的单元格内容不断变化,这意味着内容已经更新。这里我们假设内容是一个标签。我们设置了标签的文本,标签的高度肯定会改变。

      重点来了:标签的变化如何通知单元格更新?

      我们使用AutoLayout,当然我们必须更新标签的高度约束。

      而且我认为它会起作用!

      以下是详细步骤:
      1.我们为单元格的子视图设置了约束。(我认为已经完成了)
      2.其中一个标签的高度是自己改变的。(我也觉得是这样)
      3.我们得到标签的新高度,并更新标签的高度约束。(我们要做的)

      【讨论】:

        【解决方案5】:

        您似乎想根据内容更改重新加载特定单元格

        我们有几个选择

        1) 需要重新加载整个表格视图。

        否则

        2) 根据内容变化重新加载特定的单元格。

        但首选选项是重新加载特定单元格,

        为什么是因为 当您要求您的 UITableView 实例重新加载几个单元格时,tableview 将要求其数据源(-tableView:cellForRowAtIndexPath:) 获取更新的内容,以便重新加载的单元格也将具有更新的大小和更新的内容。

        当内容/高度需要根据内容更新时,尝试重新加载单元格

        希望对您有所帮助! 快乐编码:)

        【讨论】:

          【解决方案6】:

          有一个记录在案的方法可以做到这一点。见UITableView.beginUpdates()documentation:

          您也可以使用此方法后跟 endUpdates 方法来动画化行高的变化,而无需重新加载单元格。

          所以,正确的解决方案是:

          tableView.beginUpdates()
          tableView.endUpdates()
          

          另请注意,有一个功能未记录在案 - 您也可以在此处为更新动画添加完成处理程序:

          tableView.beginUpdates()
          CATransaction.setCompletionBlock {
             // this will be called when the update animation ends
          }
          
          tableView.endUpdates()
          

          但是,请轻点,它没有记录在案(但它可以工作,因为UITableView 使用CATransaction 作为动画)。

          【讨论】:

          • 谢谢苏丹。如何只更新一个单元格的高度?
          • @TIMEX 这个方法让表格查询新的高度和动画变化(与数据模型同步)。如果您只想更改一个单元格的高度,则只需在数据模型中更改一个高度(例如,仅在一个单元格中更改 label.text,而不是同时在多个单元格中更改)。
          【解决方案7】:

          您可以通过此代码获取自动单元格高度

          tableView.beginUpdates()
          // add label text update code here 
          // label.numberOfLines = label.numberOfLines == 0 ? 1 : 0
          tableView.endUpdates()
          

          下面是这个解决方案的参考:

          GitHub-RayFix-MultiLineDemo

          【讨论】:

            【解决方案8】:

            看看这个答案:Using Auto Layout in UITableView for dynamic cell layouts & variable row heights

            那里对如何实现动态单元格大小进行了非常详尽的描述。

            作为测试建议尝试将 setNeedsLayout 添加到:

            - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
            

            或

            - (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath 
            

            【讨论】:

              【解决方案9】:

              要禁用烦人的tableView 动画:

              UIView.setAnimationsEnabled(false)
              tableView.beginUpdates()
              // cell.titleLabel?.text = "title"
              // cell.detailTextLabel?.text = "Very long text ..."
              // cell.detailTextLabel?.numberOfLines = 0
              tableView.endUpdates()
              UIView.setAnimationsEnabled(true)
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2016-10-28
                • 1970-01-01
                • 2010-11-12
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多