ios 为什么 UITableViewAutomaticDimension 不起作用?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30299319/
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:00:11  来源:igfitidea点击:

why UITableViewAutomaticDimension not working?

iosobjective-cswiftuitableviewrow-height

提问by CaffeineShots

Hi there is plenty of question answering the dynamic height for UITableViewCellof UITableView. However I find it weird when I did it.

你好有很多问题回答的动态高度的UITableViewCellUITableView。然而,当我这样做时,我觉得很奇怪。

here's are some of the answer :

这是一些答案:

hereand here

这里这里

usually this would answer the dynamic height for cell

通常这将回答单元格的动态高度

tableView.estimatedRowHeight = 44.0
tableView.rowHeight = UITableViewAutomaticDimension

but in my case I wonder this line wont do anything.

但就我而言,我想知道这条线不会做任何事情。

my UITableViewis being viewed after clicking tabbar inside the splitview. Is this helpful?

UITableView单击 splitview 内的标签栏后,我正在查看。这有帮助吗?

Maybe I'm Missing something. Could anyone help me I spent 2 hours doing silly.

也许我错过了一些东西。谁能帮我我花了2个小时做傻事。

These are my constraint for title the title could be long but the label is not.

这些是我对标题的约束,标题可能很长,但标签不是。

enter image description here

在此处输入图片说明

and this is my cell

这是我的手机

enter image description here

在此处输入图片说明

回答by Zell B.

In order to make UITableViewAutomaticDimension work you have to set all left, right, bottom, and top constraints relative to cell container view. In your case you will need to add the missing bottom space to superview constraint for label under the title

为了使 UITableViewAutomaticDimension 工作,您必须设置所有与单元格容器视图相关的左、右、下和上约束。在您的情况下,您需要将缺少的底部空间添加到标题下标签的超级视图约束

回答by Eyeball

I had added constraints programmatically, and accidentally added them to the cell directly, i.e. not on the contentViewproperty. Adding the constraints to contentViewresolved it for me!

我以编程方式添加了约束,并意外地将它们直接添加到单元格中,即不在contentView属性上。添加约束来contentView为我解决它!

回答by Krunal

To set automatic dimension for row height & estimated row height, ensure following steps to make, auto dimension effective for cell/row height layout.

要为行高和估计行高设置自动尺寸,请确保按照以下步骤使自动尺寸对单元格/行高布局有效。

  • Assign and implement tableview dataSource and delegate
  • Assign UITableViewAutomaticDimensionto rowHeight & estimatedRowHeight
  • Implement delegate/dataSource methods (i.e. heightForRowAtand return a value UITableViewAutomaticDimensionto it)
  • 分配和实现 tableview 数据源和委托
  • 分配UITableViewAutomaticDimension给 rowHeight 和estimatedRowHeight
  • 实现委托/数据源方法(即heightForRowAtUITableViewAutomaticDimension为其返回值)

-

——

Objective C:

目标 C:

// in ViewController.h
#import <UIKit/UIKit.h>

@interface ViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>

  @property IBOutlet UITableView * table;

@end

// in ViewController.m

- (void)viewDidLoad {
    [super viewDidLoad];
    self.table.dataSource = self;
    self.table.delegate = self;

    self.table.rowHeight = UITableViewAutomaticDimension;
    self.table.estimatedRowHeight = UITableViewAutomaticDimension;
}

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

    return UITableViewAutomaticDimension;
}

Swift:

迅速:

@IBOutlet weak var table: UITableView!

override func viewDidLoad() {
    super.viewDidLoad()

    // Don't forget to set dataSource and delegate for table
    table.dataSource = self
    table.delegate = self

    // 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 label instance in UITableviewCell

对于 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(& 换行模式 = 截尾)
  • 设置与其父视图/单元格容器相关的所有约束(顶部、底部、左侧)。
  • 可选:设置标签的最小高度,如果你想要标签覆盖的最小垂直区域,即使没有数据。

enter image description here

在此处输入图片说明

Note: If you've more than one labels (UIElements) with dynamic length, which should be adjusted according to its content size: Adjust 'Content Hugging and Compression Resistance Priority` for labels which you want to expand/compress with higher priority.

注意:如果您有多个具有动态长度的标签(UIElements),应根据其内容大小进行调整:为您希望以更高优先级展开/压缩的标签调整“内容拥抱和压缩阻力优先级”。

回答by CamQuest

Also make sure the Lines for your UILabel in the cell is set to 0. If it is set to 1, it will not grow vertically.

还要确保单元格中 UILabel 的 Lines 设置为 0。如果设置为 1,则它不会垂直增长。

回答by Bptstmlgt

I have a specific case, and 99% of the solutions I read didn't work. I thought I'd share my experience. Hope it can helps, as I'd struggled for a couple of hours before fixing this issue.

我有一个特定的案例,我阅读的 99% 的解决方案都不起作用。我想我会分享我的经验。希望它能有所帮助,因为在解决这个问题之前我已经挣扎了几个小时。

My scenario:

我的场景

  • I'm using two TableViews in one ViewController
  • I am loading Custom Cells (xib)in those tableviews
  • Dynamic content in cells consists of two labels
  • Page uses a ScrollView
  • 在一个 ViewController 中使用了两个 TableView
  • 我正在这些 tableviews 中加载自定义单元格 (xib)
  • 单元格中的动态内容由两个标签组成
  • 页面使用ScrollView

What I needed to achieve:

我需要实现的目标

  • Dynamic TableView height
  • Dynamic TableViewCells height
  • 动态 TableView 高度
  • 动态 TableViewCells 高度

What you'll need to check to make it work smoothly:

您需要检查哪些内容才能使其顺利运行

  • Like every tutorial and answer will tell you, set all the constraints for your label/content (top, bottom, leading & trailing), and set it to the ContentView (Superview). This video tutorial will be helpful.

  • In the viewWillAppearmethod of my ViewController, I am giving one of my tableViews (tableView2) an estimated row height and then use the UITableViewAutomaticDimensionas such (and as seen in all tutorials/answers):

        override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
    
        tableView2.estimatedRowHeight = 80
        tableView2.rowHeight = UITableViewAutomaticDimension
    
    }
    
  • 就像每个教程和答案都会告诉您的那样,为您的标签/内容(顶部、底部、前导和尾随)设置所有约束,并将其设置为 ContentView(超级视图)。这个视频教程会很有帮助

  • viewWillAppear我的 ViewController的方法中,我给我的一个 tableViews ( tableView2) 一个估计的行高,然后使用它UITableViewAutomaticDimension(如所有教程/答案中所见):

        override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
    
        tableView2.estimatedRowHeight = 80
        tableView2.rowHeight = UITableViewAutomaticDimension
    
    }
    

For me, these previous steps were not enough. My TableView would simply take the estimatedRowHeight and multiply it by the number of cells. Meeeh.

对我来说,这些前面的步骤还不够。我的 TableView 将简单地采用估计的行高度并将其乘以单元格的数量。喵。

  • As I am using two different tableViews, I created an outlet for each of them, tableView1and tableView2. Allowing me to resize them in the viewDidLayoutSubviewsmethod. Feel free to ask in comment how I did this.

  • One additional step fixed it for me, by adding this to the viewDidAppearmethod:

    override func viewDidAppear(_ animated: Bool) {
    tableView1.reloadData() // reloading data for the first tableView serves another purpose, not exactly related to this question.
    tableView2.setNeedsLayout()
    tableView2.layoutIfNeeded()
    tableView2.reloadData()
    }
    
  • 当我使用两个不同的 tableViews 时,我为每个都创建了一个出口,tableView1并且tableView2. 允许我在viewDidLayoutSubviews方法中调整它们的大小。随时在评论中询问我是如何做到这一点的。

  • 一个额外的步骤为我修复了它,将它添加到viewDidAppear方法中:

    override func viewDidAppear(_ animated: Bool) {
    tableView1.reloadData() // reloading data for the first tableView serves another purpose, not exactly related to this question.
    tableView2.setNeedsLayout()
    tableView2.layoutIfNeeded()
    tableView2.reloadData()
    }
    

Hope that helps someone!

希望对某人有所帮助!

回答by Zampano

As of iOS 11 and Xcode 9.3, most of the above information is wrong. Apple's Guidesuggests setting

从 iOS 11 和 Xcode 9.3 开始,以上大部分信息都是错误的。 Apple's Guide建议设置

    tableView.estimatedRowHeight = 85.0
    tableView.rowHeight = UITableViewAutomaticDimension

WWDC 2017 session 245(Building Apps with Dynamic Type, about 16:33 into the video) suggests something similar. None of this made a difference for me.

WWDC 2017 会议 245(使用动态类型构建应用程序,视频大约 16:33)提出了类似的建议。这些都对我没有任何影响。

For a Subtitle style cell, all that's necessary to get self-sizing table view cells is to set the number of lines (in the Label section of the attributes inspector) to 0 for both the Title and Subtitle. If one of these labels is too long and you don't set the number of lines to 0, the table view cell won't adjust its size.

对于副标题样式的单元格,获得可调整大小的表格视图单元格所需要的只是将标题和副标题的行数(在属性检查器的标签部分)设置为 0。如果这些标签之一太长并且您没有将行数设置为 0,则表格视图单元格将不会调整其大小。

回答by Guy Daher

Forgot to remove tableView(heightForRowAt:indexPath:)

忘记删除了 tableView(heightForRowAt:indexPath:)

It could be the case that, like me, you accidentally forgot to removethe boilerplate code for the heightForRowAtmethod.

可能的情况是,像我一样,您不小心忘记删除heightForRowAt方法的样板代码。

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

回答by Thomas

For anyone that maybe faced the same problem with me: I struggled for an hour to make it work. A simple UIlabel with top, bottom left and right constraints. I used the willDisplayCell to pass the data to the cell and this was causing problems in cells height. As long as I put that code in cellForRow everything worked just fine. Didn't understand why this happened, maybe the cell height was calculated before willDisplayCell was called so there was no content to make the right calculation. I was just wanted to mention and probably help someone with the same problem.

对于可能与我面临同样问题的任何人:我努力了一个小时才能让它发挥作用。一个简单的 UIlabel,带有上下左右约束。我使用 willDisplayCell 将数据传递给单元格,这导致单元格高度出现问题。只要我将该代码放在 cellForRow 中,一切都运行良好。不明白为什么会发生这种情况,可能是在调用 willDisplayCell 之前计算了单元格高度,因此没有进行正确计算的内容。我只是想提一下并可能帮助有同样问题的人。

回答by Bassant Ashraf

it was working for me fine in iOS 11 and above, while breaking in iOS 10 the solution was to add

它在 iOS 11 及更高版本中对我来说很好,而在 iOS 10 中,解决方案是添加

table.rowHeight = UITableView.automaticDimension
table.estimatedRowHeight = 200 // a number and not UITableView.automaticDimension

also make sure you add "heightForRowAt" even if it works in iOS 11 and above, its needed if you support iOS 10

还要确保添加“heightForRowAt”,即使它适用于 iOS 11 及更高版本,如果您支持 iOS 10,则需要它

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

回答by Jaywant Khedkar

Try this, Simple solution it's work for me,

试试这个,简单的解决方案对我有用,

In viewDidLoad write this code,

在 viewDidLoad 中写下这段代码,

-(void)viewDidLoad 
{
[super viewDidLoad];
 self.tableView.estimatedRowHeight = 100.0; // for example. Set your average height
 self.tableView.rowHeight = UITableViewAutomaticDimension;
}

In cellForRowAtIndexPath write this code,

在 cellForRowAtIndexPath 中编写此代码,

 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
 {
  static NSString *CellIdentifier = @"Cell";
  UITableViewCell *cell = [tableView 
  dequeueReusableCellWithIdentifier:CellIdentifier];
 if (cell == nil) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] ;
  }
    cell.textLabel.numberOfLines = 0; // Set label number of line to 0
    cell.textLabel.text=[[self.arForTable objectAtIndex:indexPath.row] valueForKey:@"menu"];
    [cell.textLabel sizeToFit]; //set size to fit 
    return cell;
 }