【问题标题】:why UITableViewAutomaticDimension not working?为什么 UITableViewAutomaticDimension 不起作用?
【发布时间】:2015-07-29 17:28:55
【问题描述】:

您好,有很多问题可以回答UITableViewCell 的动态高度UITableView。但是我做的时候觉得很奇怪。

这里有一些答案:

herehere

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

tableView.estimatedRowHeight = 44.0
tableView.rowHeight = UITableView.automaticDimension

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

我的UITableView 在拆分视图中单击标签栏后被查看。这有帮助吗?

也许我错过了什么。谁能帮帮我,我花了 2 个小时做傻事。

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

这是我的牢房

【问题讨论】:

  • 您应该再次检查 UITableViewCell xib/storyboard 中的自动布局设置。你有问题 100%
  • 是的,我正在重写它。希望能找到原因
  • 如果你在那里发布你的 xib/storyboard,我可以帮你解决
  • 您是否设置了相对于单元格内容视图的顶部和底部的视图约束?
  • 我应该只做截图吗?

标签: ios objective-c swift uitableview row-height


【解决方案1】:

一种不常见的解决方案,但可以节省其他人的时间:在cellForRowAtIndexPath 中确保设置标签文本没有延迟。出于某种未知原因,我将其包裹在 DispatchQueue.main.async 块中,这意味着在实际设置标签文本之前返回单元格,因此单元格和标签永远不会扩展到文本的大小。

【讨论】:

    【解决方案2】:

    在我的情况下,我做了一切,但它并没有为我解决问题,最后,我检查了固定为 3 的标签行。将行值更改为 0 为我解决了问题。所以告诉你它必须是 0 并且必须附加约束 Top、Bottom、Left、Right 才能正常工作。

    【讨论】:

      【解决方案3】:

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

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

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

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

        • 谢谢!我也为这个问题而苦苦挣扎。对我来说似乎是一个 UIKit 错误,但这解决了它!
        【解决方案5】:

        我有一个新的解决方案..它对我有用。

        基本上UITableViewAutomaticDimension改名为UITableView.automaticDimension...我希望..它不会

        【讨论】:

          【解决方案6】:

          对于我的设置,我首先仔细检查了情节提要中的约束 UITableViewCell 从上到下是明确的,然后不得不在 2 个地方修改代码。

          1. UITableViewDelegatetableView(_:heightForRowAt:)

            func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
                return UITableView.automaticDimension
                // return UITableViewAutomaticDimension for older than Swift 4.2
            }
            
          2. UITableViewDelegatetableView(_:estimatedHeightForRowAt:)

            func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
                return UITableView.automaticDimension
                // return UITableViewAutomaticDimension for older than Swift 4.2
            }
            

          第 1 步和第 2 步可让您仅对特定行应用自动调整大小。申请整个UITableView,使用:

          tableView.rowHeight = UITableView.automaticDimension
          tableView.estimatedRowHeight = UITableView.automaticDimension
          // return UITableViewAutomaticDimension for older than Swift 4.2
          

          【讨论】:

            【解决方案7】:

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

            • 分配和实现 tableview 数据源和委托
            • UITableViewAutomaticDimension 分配给rowHeight 和estimatedRowHeight
            • 实现委托/数据源方法(即heightForRowAt 并向其返回值UITableViewAutomaticDimension

            -

            目标 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;
            }
            

            斯威夫特:

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

            UITableviewCell 中的标签实例

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

            注意:如果您有多个标签(UIElements)具有动态长度,应根据其内容大小进行调整:为您的标签调整'Content Hugging and Compression Resistance Priority'想要以更高的优先级展开/压缩。

            【讨论】:

            • 实现 heightForRowAt 并返回 UITableView.automaticDimension 工作
            • 不要在estimatedHeightForRowAt 委托方法中返回automaticDimension。它用于向表格视图提示单元格的大小。
            【解决方案8】:

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

                tableView.estimatedRowHeight = 85.0
                tableView.rowHeight = UITableViewAutomaticDimension
            

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

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

            【讨论】:

            • both 标签的 numberOfLines 设置为 0 可让您使用非自定义 UITableViewCells 自行调整大小。非常感谢!
            【解决方案9】:

            确保单元格中的所有视图都受限于内容视图而不是单元格。

            正如苹果所说:

            在单元格的内容视图中布置表格视图单元格的内容。要定义单元格的高度,您需要一个完整的约束链和视图(具有定义的高度)来填充内容视图的顶部边缘和底部边缘之间的区域。

            【讨论】:

              【解决方案10】:

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

              在viewDidLoad中写下这段代码,

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

              在 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;
               }
              

              【讨论】:

                【解决方案11】:

                我有三个水平项目,最左边的有一个向左的约束,中间的一个有顶部、底部、左边的项目和右边的项目。右边有一个右边,左边有中间项。解决方案是向中间项目(我的标签)添加额外的左右约束,这些约束 >= 单元格中的某个数字。

                【讨论】:

                  【解决方案12】:

                  为了使 UITableViewAutomaticDimension 工作,您需要确保将所有 4 个角的约束添加到超级视图。在大多数情况下,它与 UILabel 配合得很好,但有时我发现当 UILabel 当时不能正常工作时,UITextView 可以解决问题。所以尝试切换到 UITextView 并确保 Scrolling Enabled 在情节提要中未选中,或者您也可以通过编程方式设置它。

                  【讨论】:

                    【解决方案13】:

                    忘记删除tableView(heightForRowAt:indexPath:)

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

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

                    【讨论】:

                    • ...当然也不要给它一个高度限制;-)
                    • 这个方法可以返回UITableViewAutomaticDimension。对于子类化
                    【解决方案14】:

                    我有一个具体案例,我阅读的 99% 的解决方案都不起作用。我想我会分享我的经验。希望它可以提供帮助,因为在解决此问题之前我已经挣扎了几个小时。

                    我的场景

                    • 我在一个 ViewController 中使用 两个 TableViews
                    • 我在这些表格视图中加载自定义单元格 (xib)
                    • 单元格中的动态内容由两个标签组成
                    • 页面使用 ScrollView

                    我需要实现的目标

                    • 动态表格视图高度
                    • 动态 TableViewCells 高度

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

                    • 就像每个教程和答案都会告诉您的那样,设置标签/内容的所有约束(顶部、底部、前导和尾随),并将其设置为 ContentView(超级视图)。 This video tutorial will be helpful.

                    • 在我的 ViewController 的 viewWillAppear 方法中,我给我的一个 tableViews (tableView2) 一个估计的行高,然后使用 UITableViewAutomaticDimension 原样(在所有教程/答案中都可以看到):

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

                    对我来说,之前的这些步骤还不够。我的 TableView 将简单地采用estimatedRowHeight 并将其乘以单元格的数量。嗯。

                    • 当我使用两个不同的 tableViews 时,我为它们中的每一个创建了一个 outlet,tableView1tableView2。允许我在 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()
                      }
                      

                    希望对某人有所帮助!

                    【讨论】:

                    • 最后一条建议(但没有双 IBOutlet)在 2019 年仍然有用。
                    【解决方案15】:

                    在我的情况下,我有两个 UITableView,我不得不修改这个方法

                    -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
                        CGFloat height = 0.0;
                        if (tableView == self.tableviewComments) {
                            return UITableViewAutomaticDimension;
                        }else if (tableView == self.tableViewFriends) {
                            height = 44.0;
                        }
                        return height;
                    }
                    

                    【讨论】:

                      【解决方案16】:

                      我以编程方式添加了约束,并且不小心将它们直接添加到单元格中,即不在 contentView 属性上。将约束添加到contentView 为我解决了问题!

                      【讨论】:

                      • 是的,我们需要清楚地知道我们使用什么约束,因为缺少或添加一个约束可能导致歧义或不满足约束。感谢您的回答!
                      • 我知道这是旧的,但我认为这不是正确的方法。如果您不将约束添加到内容视图。当您为单元格打开任何编辑样式(如删除)或移动它自己的行时,视图会扭曲。
                      • @Esko918 我认为您读错了他的答案。他说您需要向contentView 添加约束。我还意外地在UITableViewCellcontentViewcontentView 上添加了约束
                      • 我就是这么说的。如果您不将约束添加到内容视图,则当您选择删除或移动行等编辑样式时,视图将扭曲。您不应该直接修改单元格视图,因为当您点击编辑模式并且单元格向右移动时 UIKit 会修改单元格布局。您应该将所有子视图和布局约束添加到内容视图。不是视图本身
                      【解决方案17】:

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

                      【讨论】:

                        【解决方案18】:

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

                        【讨论】:

                        • 请注意,您可能必须将某些视图的底部约束设置为 >= 而不仅仅是 = 以允许它们随着单元格的动态高度而增长。这就是我的诀窍。
                        • @khunshan 你确定你没有使用尺寸等级吗?
                        • @ZellB。是的,你是对的。由于限制,它缺少 iPhone 类。 (Y)
                        猜你喜欢
                        • 2019-04-19
                        • 1970-01-01
                        • 2016-04-07
                        • 1970-01-01
                        • 1970-01-01
                        • 2015-03-06
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多