如何让 UITableView 行高自动调整为 UITableViewCell 的大小?

Posted

技术标签:

【中文标题】如何让 UITableView 行高自动调整为 UITableViewCell 的大小?【英文标题】:how to get a UITableView row height to auto-size to the size of the UITableViewCell? 【发布时间】:2011-03-01 23:41:01 【问题描述】:

如何让 UITableView 的行高自动调整为 UITableViewCell 的大小?

所以假设我在 Interface Builder 中创建 UITableViewCell,并且它的高度超过标准尺寸,我怎样才能让 UITableView 行高自动调整到它? (即,与手动测量界面生成器中的高度相比,而不是以编程方式设置它)

【问题讨论】:

您可以在此处找到适用于 ios 7 及更高版本的答案。 ***.com/questions/18746929/… 【参考方案1】:

http://www.cimgf.com/2009/09/23/uitableviewcell-dynamic-height/ 是一个很好的教程。

主要是

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

  // Get the text so we can measure it
  NSString *text = [items objectAtIndex:[indexPath row]];
  // Get a CGSize for the width and, effectively, unlimited height
  CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);
  // Get the size of the text given the CGSize we just made as a constraint
  CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
  // Get the height of our measurement, with a minimum of 44 (standard cell size)
  CGFloat height = MAX(size.height, 44.0f);
  // return the height, with a bit of extra padding in
  return height + (CELL_CONTENT_MARGIN * 2);

【讨论】:

这是人们所期望的 :-) 我的自定义单元格具有各种属性(例如 ImageView、Label、TextView)。在这种情况下,我的 NSString *text = [items objectAtIndex:[indexPath row]] 会是什么? NSString sizeWithFont: 现已弃用。【参考方案2】:

如果所有单元格都相同,请将UITableView 上的rowHeight 属性设置为单元格的大小。如果它们根据内容都不同,您将必须实现 -tableView:heightForRowAtIndexPath: 并根据您的数据源计算每行的高度。

【讨论】:

那么没有什么灵丹妙药可以让 ios 自动为您解决这个问题? 很遗憾现在没有。 Brian 的回答为实现 tableView:heightForRowAtIndexPath 提供了一个很好的步骤 如果需要混合使用固定和自动计算的行,tableView:heightForRowAtIndexPath: 可以在需要的地方返回固定值,UITableViewAutomaticDimension 用于应该自动计算的行。【参考方案3】:

在带有 tableview 的 xib 中,您可以添加一个单元格对象并将其链接到源代码中的 IBOutlet。你不会在任何地方使用它,你只会使用它来获取单元格的高度。

然后,在tableView:heightForRowAtIndexPath: 中,您可以使用该对象来获取高度。它不是 100% 自动的,但至少这样可以省去您在 IB 的单元格视图中进行更改时手动更新源代码的麻烦。


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

    return myDummyCellObject.bounds.size.height;

如果所有行都属于同一类型(单元格),您可以通过编程设置tableView.rowHeight 属性,而不是实现上面的委托方法。取决于你的场景。

哦,别忘了在 -dealloc 中释放 myDummyCellObject。

【讨论】:

如果您已将属性添加为 IBOutlet,则无需解除分配。您不再负责管理它。但是现在有了 ARC,所有这些 dealloc 的东西都或多或少没有实际意义。【参考方案4】:
self.tableView.estimatedRowHeight = 65.0; // Estimate the height you want
self.tableView.rowHeight = UITableViewAutomaticDimension; // auto change heights for multiple lines cells.

实现 UITableViewDataSource 所需方法时:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
    cell.textLabel.text = [self.todoArray objectAtIndex:indexPath.row];
    cell.textLabel.numberOfLines = 0; // allow multiple lines showing up

    return cell;

【讨论】:

这个逻辑不应该在cellForRowAtIndexPath方法中。【参考方案5】:

从 iOS 8 开始,您可以通过在表格视图中指定这些选项来选择 work with self-sizing cells:

tableView.estimatedRowHeight = 85.0
tableView.rowHeight = UITableView.automaticDimension

只要系统可以根据现有约束或内容计算行,这将起作用。请注意,如果您设置了 automaticDimension,则不会调用 heightForRowAtIndexPath!


有时对于更复杂的数据,一些单元格可以自动计算,但其他单元格需要特定的高度计算逻辑。在这种情况下,您应该设置estimatedRowHeight,然后使用可以正常工作的单元格的自动逻辑实现cellForRowAtIndexPath:

// Set the estimated row height in viewDidLoad, but *not* automatic dimension!
override func viewDidLoad() 
    // other viewDidLoad stuff...
    tableView.estimatedRowHeight = 85.0
    tableView.delegate = self


// Then implement heightForRowAtIndexPath delegate method
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat 
    if theAutomaticCalculationWorksForThisRow 
        return UITableView.automaticDimension
     else 
        // Calculate row height based on custom logic...
        let rowHeight = 85.0
        return rowHeight
    

【讨论】:

以上是关于如何让 UITableView 行高自动调整为 UITableViewCell 的大小?的主要内容,如果未能解决你的问题,请参考以下文章

qt中QTableWidget怎么根据内容自动调整列宽行高?

在 UITableView 中使用自动布局进行动态单元格布局和可变行高

在 UITableView 中使用自动布局进行动态单元格布局和可变行高

UITableView 自动调整行约束在 iPhone 6Plus 上神秘地打破

tableView 未设置自动行高

不使用 AutoLayout 的 UITableView 动态行高