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

时间:2015-05-27 23:15:32

标签: ios swift xcode uitableview row-height

可变长度的动态文本被注入tableview单元格标签。为了tableview细胞'我已在viewDidLoad()

中实现了动态调整大小的高度
self.tableView.estimatedRowHeight = 88.0
self.tableView.rowHeight = UITableViewAutomaticDimension

这适用于尚未滚动到的单元格(在滚动到单元格时调用UITableViewAutomaticDimention),但在加载带有数据的表时最初在屏幕上呈现的单元格不适用。< / p>

我尝试过简单地重新加载数据(如许多其他资源所示):

self.tableView.reloadData()
{p} viewDidAppear()viewWillAppear()中的

并没有用。我迷了..有没有人知道如何让xcode渲染最初在屏幕上加载的单元格的动态高度?

如果有更好的替代方法,请告诉我。

24 个答案:

答案 0 :(得分:95)

试试这个:

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

修改

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

Swift 4

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

Swift 4.2

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

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

PS:需要使用顶部和底部约束才能生效。

Here is example

答案 1 :(得分:30)

使用此:

tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 300

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

此外,在故事板中不要设置包含大量数据的标签的高度。给它top, bottom, leading, trailing约束。

答案 2 :(得分:12)

SWIFT 3

tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 160

和!!! 在storyBoard中:你必须设置TOP&amp;标签的BOTTOM约束。 没别了。

答案 3 :(得分:10)

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

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

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

但那没有用。所以我意识到内容不会变得比100px更大,所以我将默认的单元格高度设置为{{ 1}}(大于潜在内容)并在控制器108px中反映出来:

viewDidLoad()

这实际上允许代码缩小将初始标签设置为正确的大小。换句话说,它永远不会扩展到更大的尺寸,但总是会缩小......而且,self.tableView.rowHeight = UITableViewAutomaticDimension self.tableView.estimatedRowHeight = 108.0 中不需要额外的self.tableView.reloadData()

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

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

答案 4 :(得分:7)

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

  1. 在表格视图单元格内设置视图的右边约束(主要包括为视图提供正确的顶部,底部和traling约束)
  2. 在viewDidLoad()

    中调用TableView的这些属性
     tableView.rowHeight = UITableViewAutomaticDimension
    
     tableView.estimatedRowHeight = 140
    
  3. This是一个关于自动调整大小(动态表视图单元格)的精彩教程,用swift 3编写。

答案 5 :(得分:7)

设置行高的自动尺寸&amp;估计行高并确保以下步骤:

@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(&amp; line break mode = truncate tail)
  • 相对于其superview / cell容器设置所有约束(顶部,底部,右侧)。
  • 可选:如果您希望标签覆盖最小垂直区域,即使没有数据,也可以设置标签的最小高度。

以下是具有动态高度限制的样本标签。

enter image description here

答案 6 :(得分:4)

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

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

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

答案 7 :(得分:2)

尝试

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

我遇到了同样的问题,对我有用。

答案 8 :(得分:2)

要使UITableViewCell的自动调整工作,请确保您正在进行这些更改:

  • 在Storyboard中,您的UITableView应该只包含动态原型单元格(它不应该使用静态 细胞)否则自动调整将无法正常工作。
  • 在故事板中你的UITableViewCell UILabel配置了所有4个顶部,底部, 领先和尾随约束。
  • 在故事板中你的UITableViewCell UILabel的行数应为0
  • 在你的UIViewController中 viewDidLoad函数设置在UITableView属性下面:

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

答案 9 :(得分:2)

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

快乐编码:)

答案 10 :(得分:1)

我的灵感来自你的解决方案并尝试了另一种方式。

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

这适合我。

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

如果这样可行,请回答这个答案,以便我确定这个解决方案。

答案 11 :(得分:1)

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

您需要添加顶部,底部,右侧和左侧约束

答案 12 :(得分:1)

我用这些

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

    return 100
}

答案 13 :(得分:0)

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

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

答案 14 :(得分:0)

快速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
}

答案 15 :(得分:0)

做两件事很简单:

  1. 设置自动高度

    tableView.rowHeight = UITableView.automaticDimension

  2. 从顶部到底部创建具有 FULL 约束的所有TableViewCell。最后一个元素**必须**定义一些底部间距以结束单元格。

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

答案 16 :(得分:0)

使用静态UITableView时,我在UILabel中设置了所有值,然后调用tableView.reloadData()

答案 17 :(得分:0)

就我而言-在分镜脚本中,我有两个标签,如下图所示, 两个标签均已设置了所需的宽度值,然后再使其相等。取消选择后,它将变为自动,并且像往常一样,下面的内容应该像魅力一样起作用。

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

enter image description here

答案 18 :(得分:0)

除了其他人所说的,

设置与总览有关的标签约束!

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

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

然后在ViewDidLoad中添加:

tableView.estimatedRowHeight = 695

tableView.rowHeight = UITableViewAutomaticDimension

答案 19 :(得分: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;

答案 20 :(得分:0)

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

答案 21 :(得分:0)

我最初也遇到过这个问题,我已经从这段代码中解决了我的问题 尽量避免使用self.tableView.reloadData()代替此代码进行动态高度

[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationFade];

答案 22 :(得分:-2)

enter code here 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);

答案 23 :(得分:-3)

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

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

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