ios UITableView 单元格的动态高度问题 (Swift)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30494702/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 06:05:43  来源:igfitidea点击:

Dynamic Height Issue for UITableView Cells (Swift)

iosswiftxcodeuitableviewrow-height

提问by simplexity

Dynamic text of variable length are being injected into tableview cell labels. In order for the tableview cells' heights to be dynamically sized, I have implemented in viewDidLoad():

可变长度的动态文本被注入到 tableview 单元格标签中。为了动态调整 tableview 单元格的高度,我在viewDidLoad()

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

This works nicely for the cells that have yet to be scrolled to (as UITableViewAutomaticDimentionis called upon scrolling to the cell), but not for the cells that are initially rendered onscreen upon loading the table with data.

这对于尚未UITableViewAutomaticDimention滚动到的单元格非常有效(如滚动到单元格时所调用),但不适用于在加载带有数据的表格时最初呈现在屏幕上的单元格。

I have tried simply reloading the data (as suggested in many other resources):

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

self.tableView.reloadData()

in both viewDidAppear()and viewWillAppear()and it was to no avail. I am lost.. does anyone know how to have xcode render the dynamic height for the cells loaded initially on screen?

在两者viewDidAppear()viewWillAppear()它都无济于事。我迷路了.. 有谁知道如何让 xcode 渲染最初加载到屏幕上的单元格的动态高度?

Please let me know, if there is a better alternate method.

请让我知道,如果有更好的替代方法。

回答by iDhaval

Try This:

尝试这个:

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

EDIT

编辑

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

Swift 4

斯威夫特 4

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

Swift 4.2

斯威夫特 4.2

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

Define above Both Methods.
It solves the problem.

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

PS: Top and bottom constraints is required for this to work.

PS:需要顶部和底部约束才能工作。

Here is example

这是例子

回答by ami rt

Use this:

用这个:

tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 300

and don't use: heightForRowAtIndexPathdelegate function

并且不要使用:heightForRowAtIndexPath委托函数

Also, in the storyboard don't set the height of the label that contains a large amount of data. Give it top, bottom, leading, trailingconstraints.

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

回答by W?odzimierz Wo?niak

SWIFT 3

斯威夫特 3

tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 160

AND!!! In storyBoard: You HAVE TO set TOP & BOTTOM constraints for your Label. Nothing else.

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

回答by simplexity

This strange bug was solved through Interface Builder parameters as the other answers did not resolve the issue.

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

All I did was make the default label size larger than the content potentially could be and have it reflected in the estimatedRowHeightheight too. Previously, I set the default row height in Interface Builder to 88pxand reflected it like so in my controller viewDidLoad():

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

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

But that didn't work.So I realized that content wouldn't ever become larger than maybe 100px, so I set the default cell height to 108px(larger than the potential content) and reflected it like so in the controller viewDidLoad():

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

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

This actually allowed the code to shrink downthe initial labels to the correct size. In other words, it never expanded out to a larger size, but could always shrink down... Also, no additional self.tableView.reloadData()was needed in viewWillAppear().

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

I know this does not cover highly variable content sizes, but this worked in my situation where the content had a maximum possible character count.

我知道这不包括高度可变的内容大小,但这在我的情况下有效,其中内容具有最大可能的字符数。

Not sure if this is a bug in Swift or Interface Builder but it works like a charm. Give it a try!

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

回答by Krunal

Set automatic dimension for row height & estimated row height and ensure following steps:

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

@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
}

For Example: if you have a label in your UITableviewCell then,

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

  • Set number of lines = 0 (& line break mode = truncate tail)
  • Set all constraints (top, bottom, right left) with respect to its superview/ cell container.
  • Optional: Set minimum height for label, if you want minimum vertical area covered by label, even if there is no data.
  • 设置行数 = 0(& 换行模式 = 截尾)
  • 设置与其父视图/单元格容器相关的所有约束(顶部、底部、左侧)。
  • 可选:设置标签的最小高度,如果你想要标签覆盖的最小垂直区域,即使没有数据。

Here is sample label with dynamic height constraints.

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

enter image description here

在此处输入图片说明

回答by osama

Dynamic sizing cell of UITableView required 2 things

UITableView 的动态大小调整单元格需要 2 件事

  1. Setting the the right constraint of your view inside the table view cell (mostly it includes giving your view proper top , bottom and traling constraints)
  2. Calling these properties of TableView in viewDidLoad()

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

     tableView.rowHeight = UITableViewAutomaticDimension
    
     tableView.estimatedRowHeight = 140
    

Thisis a wonderfull tutorial on self-sizing (dynamic table view cells) written in swift 3 .

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

回答by Ahmed Lotfy

For Swift 3 you can use the following:

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

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

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

回答by Anshul Sharma

To make autoresizing of UITableViewCell to work make sure you are doing these changes :

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

  • In Storyboard your UITableView should only contain Dynamic Prototype Cells (It shouldn't use static cells) otherwise autoresizing won't work.
  • In Storyboard your UITableViewCell's UILabel has configured for all 4 constraints that is top, bottom, leading and trailing constraints.
  • In Storyboard your UITableViewCell's UILabel's number of lines should be 0
  • In your UIViewController's viewDidLoad function set below UITableView Properties :

    self.tableView.estimatedRowHeight = <minimum cell height> 
    self.tableView.rowHeight = UITableViewAutomaticDimension
    
  • 在 Storyboard 中,您的 UITableView 应仅包含动态原型单元格(不应使用静态单元格),否则自动调整大小将不起作用。
  • 在 Storyboard 中,您的 UITableViewCell 的 UILabel 已为所有 4 个约束配置,即顶部、底部、前导和尾随约束。
  • 在 Storyboard 中,您的 UITableViewCell 的 UILabel 的行数应为 0
  • 在 UIViewController 的 viewDidLoad 函数中,设置在 UITableView Properties 下方:

    self.tableView.estimatedRowHeight = <minimum cell height> 
    self.tableView.rowHeight = UITableViewAutomaticDimension
    

回答by Maickell Vilela

Try

尝试

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

I had the same problem and it works for me.

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

回答by iOS

For Swift i checked this answer in iOS 9.0 and iOS 11 also (Xcode 9.3)

对于 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
}

Here you need to add top, bottom, right and left constraints

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