86

可变长度的文本数据被注入到 tableview 单元格标签中。为了正确调整每个单元格的高度,我已经实现了viewDidLoad()

self.tableView.estimatedRowHeight = 88.0
self.tableView.rowHeight = UITableViewAutomaticDimension

这估计高度为 88.0 像素,如果更大,则应自动调整高度。它非常适用于尚未滚动到的单元格(在滚动UITableViewAutomaticDimention单元格时调用),但不适用于在加载数据表时最初呈现在屏幕上的单元格。

我尝试重新加载数据(如许多其他资源中所建议的那样):

self.tableView.reloadData()

在这两者中viewDidAppear()viewWillAppear()没有帮助。我迷路了..有谁知道如何渲染最初在屏幕上加载的单元格的动态高度?

4

25 回答 25

123

尝试这个:

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

编辑

func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

斯威夫特 4

func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

斯威夫特 4.2

func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
    return UITableView.automaticDimension
}

定义以上两种方法。
它解决了这个问题。

PS:为此需要顶部和底部约束。

这是示例

于 2015-05-28T04:52:40.533 回答
42

用这个:

tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 300

并且不要使用:heightForRowAtIndexPath委托功能

另外,在情节提要中不要设置包含大量数据的标签的高度。给它top, bottom, leading, trailing约束。

于 2016-06-11T03:08:44.137 回答
17

斯威夫特 3

tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 160

和!!!在故事板中:您必须为标签设置顶部和底部约束。没有其他的。

于 2017-01-10T19:36:25.823 回答
11

这个奇怪的错误是通过 Interface Builder 参数解决的,因为其他答案没有解决这个问题。

我所做的只是使默认标签大小大于内容可能的大小,并将其也反映在estimatedRowHeight高度中。以前,我将 Interface Builder 中的默认行高设置为88px并将其反映在我的控制器中viewDidLoad()

self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.estimatedRowHeight = 88.0

但这没有用。所以我意识到内容永远不会变得比可能更大100px,所以我将默认单元格高度设置为108px(大于潜在内容)并将其反映在控制器中viewDidLoad()

self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.estimatedRowHeight = 108.0

这实际上允许代码将初始标签缩小到正确的大小。换句话说,它永远不会扩大到更大的尺寸,但总是可以缩小......而且,self.tableView.reloadData()viewWillAppear().

我知道这并不涵盖高度可变的内容大小,但这适用于内容具有最大可能字符数的情况。

不确定这是否是 Swift 或 Interface Builder 中的错误,但它就像一个魅力。试试看!

于 2015-05-29T15:35:58.303 回答
10

为行高和估计行高设置自动尺寸,并确保以下步骤:

@IBOutlet weak var table: UITableView!

override func viewDidLoad() {
    super.viewDidLoad()

    // Set automatic dimensions for row height
    // Swift 4.2 onwards
    table.rowHeight = UITableView.automaticDimension
    table.estimatedRowHeight = UITableView.automaticDimension


    // Swift 4.1 and below
    table.rowHeight = UITableViewAutomaticDimension
    table.estimatedRowHeight = UITableViewAutomaticDimension

}



// UITableViewAutomaticDimension calculates height of label contents/text
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    // Swift 4.2 onwards
    return UITableView.automaticDimension

    // Swift 4.1 and below
    return UITableViewAutomaticDimension
}

例如:如果你的 UITableviewCell 中有一个标签,那么,

  • 设置行数 = 0(& 换行模式 = 截断尾部)
  • 设置关于其超级视图/单元格容器的所有约束(顶部、底部、左右)。
  • 可选:设置标签的最小高度,如果你想要标签覆盖的最小垂直区域,即使没有数据。

这是具有动态高度约束的示例标签。

在此处输入图像描述

于 2017-10-13T12:12:41.793 回答
7

对于 Swift 3,您可以使用以下内容:

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}
于 2017-01-18T07:58:15.217 回答
7

UITableView 的动态调整单元格需要两件事

  1. 在表格视图单元格内设置视图的正确约束(主要包括为视图提供适当的顶部、底部和跟踪约束)
  2. 在 viewDidLoad() 中调用 TableView 的这些属性

     tableView.rowHeight = UITableViewAutomaticDimension
    
     tableView.estimatedRowHeight = 140
    

是一个用 swift 3 编写的关于自动调整大小(动态表格视图单元格)的精彩教程。

于 2017-04-03T07:34:17.553 回答
3

对于斯威夫特 4.2

@IBOutlet weak var tableVw: UITableView!

override func viewDidLoad() {
    super.viewDidLoad()

    // Set self as tableView delegate
    tableVw.delegate = self

    tableVw.rowHeight = UITableView.automaticDimension
    tableVw.estimatedRowHeight = UITableView.automaticDimension
}

// UITableViewDelegate Method 
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {

    return UITableView.automaticDimension
}

快乐编码:)

于 2019-02-20T06:51:22.703 回答
2

对于 Swift,我也在 iOS 9.0 和 iOS 11 中检查了这个答案(Xcode 9.3)

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

这里需要添加上下左右约束

于 2018-05-29T09:10:03.907 回答
2

我用这些

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {

    return 100
}
于 2019-03-11T17:15:26.923 回答
2

除了别人说的,

设置标签相对于监督的约束!

因此,与其将标签的约束相对于它周围的其他事物放置,不如将其约束到表格视图单元格的内容视图。

然后,确保您的标签的高度设置为大于或等于 0,并且行数设置为 0。

然后在ViewDidLoad添加:

tableView.estimatedRowHeight = 695

tableView.rowHeight = UITableViewAutomaticDimension
于 2018-06-20T20:28:20.393 回答
2

要使 UITableViewCell 的自动调整大小起作用,请确保您正在进行以下更改:

  • 在 Storyboard 中,您的 UITableView 应该只包含动态原型单元格(它不应该使用静态单元格),否则自动调整大小将不起作用。
  • 在 Storyboard 中,您的 UITableViewCell 的 UILabel 已配置所有 4 个约束,即顶部、底部、前导和尾随约束。
  • 在情节提要中,您的 UITableViewCell 的 UILabel 的行数应为 0
  • 在 UITableView 属性下设置的 UIViewController 的 viewDidLoad 函数中:

    self.tableView.estimatedRowHeight = <minimum cell height> 
    self.tableView.rowHeight = UITableViewAutomaticDimension
    
于 2017-06-01T20:50:32.800 回答
2

做两件事时这很简单:

  1. 设置自动高度
tableView.rowHeight = UITableView.automaticDimension
  1. 从上到下创建所有具有FULL约束的TableViewCell 。最后一个元素必须定义一些底部间距来结束单元格。

因此布局引擎可以计算单元格高度并正确应用该值。

于 2019-08-29T10:18:00.490 回答
2

尝试

override func viewWillAppear(animated: Bool) {
    self.tableView.layoutSubviews()
}

我有同样的问题,它对我有用。

于 2016-04-15T14:26:03.250 回答
2

就我而言 - 在情节提要中,我有两个标签,如下图所示, 两个标签都在我使其相等之前设置了所需的宽度值。一旦您取消选择,它将变为自动,并且像往常一样拥有以下内容应该像魅力一样工作。

1.rowHeight = UITableView.automaticDimension, and
2.estimatedRowHeight = 100(In my case).
3.make sure label number of lines is zero.

在此处输入图像描述

于 2019-07-19T11:42:42.783 回答
1

不幸的是,我不确定我错过了什么。上述方法不适用于我获取 xib 单元格的高度或让 layoutifneeded() 或 UITableView.automaticDimension 进行高度计算。我一直在寻找和尝试 3 到 4 晚,但找不到答案。不过,这里或另一篇文章中的一些答案确实为我提供了解决方法的提示。这是一种愚蠢的方法,但它有效。只需将所有单元格添加到数组中。然后在 xib 故事板中设置每个高度约束的出口。最后,将它们添加到 heightForRowAt 方法中。如果您不熟悉这些 API,这很简单。

斯威夫特 4.2

CustomCell.Swift

@IBOutlet weak var textViewOneHeight: NSLayoutConstraint!
@IBOutlet weak var textViewTwoHeight: NSLayoutConstraint!
@IBOutlet weak var textViewThreeHeight: NSLayoutConstraint!

@IBOutlet weak var textViewFourHeight: NSLayoutConstraint!
@IBOutlet weak var textViewFiveHeight: NSLayoutConstraint!

MyTableViewVC.Swift

.
.
var myCustomCells:[CustomCell] = []
.
.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = Bundle.main.loadNibNamed("CustomCell", owner: self, options: nil)?.first as! CustomCell

.
.
myCustomCells.append(cell)
return cell

}


override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {

   let totalHeight = myCustomCells[indexPath.row].textViewOneHeight.constant + myCustomCells[indexPath.row].textViewTwoHeight.constant +  myCustomCells[indexPath.row].textViewThreeHeight.constant + myCustomCells[indexPath.row].textViewFourHeight.constant + myCustomCells[indexPath.row].textViewFiveHeight.constant

  return totalHeight + 40 //some magic number


}
于 2019-03-11T16:42:05.777 回答
1

我只是受到您的解决方案的启发并尝试了另一种方式。

请尝试添加tableView.reloadData()viewDidAppear().

这对我有用。

我认为滚动背后的东西与reloadData“相同”。滚动屏幕时,就像调用reloadData()when viewDidAppear

如果可行,请回复此答案,以便我确定此解决方案。

于 2016-03-23T17:40:46.577 回答
0

我最初也遇到了这个问题,我已经从这段代码中解决了我的问题,尝试避免使用self.tableView.reloadData()而不是这个代码来获取动态高度

[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationFade];
于 2015-05-28T05:13:50.773 回答
0

使用 staticUITableView时,我设置了UILabels 中的所有值,然后调用tableView.reloadData().

于 2019-08-26T13:52:55.820 回答
0
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.estimatedRowHeight = 88.0

并且不要忘记为标签添加botton 约束

于 2019-08-29T10:57:34.240 回答
0

您应该为单元格视图/视图上的每个对象设置TOPBOTTOMHEIGHT的所有约束,并删除存在的中间 Y位置(如果有)。因为您没有这样做,所以将工件放在另一个视图上。

于 2017-06-26T14:58:12.217 回答
0

对于目标 c,这是我很好的解决方案之一。它对我有用。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    cell.textLabel.text = [_nameArray objectAtIndex:indexPath.row];
    cell.textLabel.numberOfLines = 0;
    cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping;
}

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

我们需要应用这两个更改。

1)cell.textLabel.numberOfLines = 0;
  cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping;

2)return UITableViewAutomaticDimension;
于 2018-03-08T05:25:22.430 回答
-1
self.Itemtableview.estimatedRowHeight = 0;
self.Itemtableview.estimatedSectionHeaderHeight = 0;
self.Itemtableview.estimatedSectionFooterHeight = 0;


[ self.Itemtableview reloadData];
self.Itemtableview.frame = CGRectMake( self.Itemtableview.frame.origin.x,  self.Itemtableview.frame.origin.y,  self.Itemtableview.frame.size.width,self.Itemtableview.contentSize.height + self.Itemtableview.contentInset.bottom + self.Itemtableview.contentInset.top);
于 2018-07-11T06:28:45.563 回答
-1

斯威夫特 5 享受

tablev.rowHeight = 100
tablev.estimatedRowHeight = UITableView.automaticDimension


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = self.tablev.dequeueReusableCell(withIdentifier: "ConferenceRoomsCell") as! ConferenceRoomsCell
    cell.lblRoomName.numberOfLines = 0
    cell.lblRoomName.lineBreakMode = .byWordWrapping
    cell.lblRoomName.text = arrNameOfRooms[indexPath.row]
    cell.lblRoomName.sizeToFit()
    return cell
}
于 2020-11-03T09:52:47.300 回答
-3

设置适当的约束并将委托方法更新为:

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

这将解决动态单元格高度问题。如果不是,您需要检查约束。

于 2017-02-10T11:15:23.297 回答