ios 使用自动布局时的 UITableView 内容大小

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

UITableView content size while using auto-layout

iosuitableviewautolayout

提问by OnkarK

I want to calculate Content size of my UITableView. I am using autolayout with height UITableViewAutomaticDimension.

我想计算我的UITableView. 我正在使用具有高度的自动布局UITableViewAutomaticDimension

Tried to get [UITableView contentsize]after reloading tableview, in that case height get calculated based on estimatedRowHeight.

尝试[UITableView contentsize]在重新加载 tableview 后获取,在这种情况下,高度基于estimatedRowHeight.

self.tableView.estimatedRowHeight = 50;
self.tableView.rowHeight = UITableViewAutomaticDimension;

Delegate -

代表 -

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

Trying to get content size and assign it to height constrain.

尝试获取内容大小并将其分配给高度约束。

[self.tableView reloadData];
[self.tableView layoutIfNeeded];
self.tableHeightConstraint.constant = self.tableView.contentSize.height;

Any suggestions? Thanks in advance.

有什么建议?提前致谢。

Edit:

编辑:

Finally I am solved my problem with some tweak. I changed tableview height to max (In my case 300 is max) before reloading data on table, so tableview has space to resize all cells.

最后我通过一些调整解决了我的问题。在重新加载表上的数据之前,我将 tableview 高度更改为 max(在我的情况下为 300 最大),因此 tableview 有空间来调整所有单元格的大小。

self.tableHeightConstraint.constant = 300;
[self.tableView reloadData];
[self.tableView layoutIfNeeded];
self.tableHeightConstraint.constant = self.tableView.contentSize.height;

Thanks for help.

感谢帮助。

回答by OnkarK

Finally I am solved my problem with some tweak. I changed tableview height to max (Objective-C: CGFLOAT_MAX, Swift: CGFloat.greatestFiniteMagnitude) before reloading data on table, so tableview has space to resize all cells.

最后我通过一些调整解决了我的问题。在重新加载表上的数据之前CGFLOAT_MAX,我将 tableview 高度更改为 max (Objective-C: , Swift: CGFloat.greatestFiniteMagnitude),因此 tableview 有空间调整所有单元格的大小。

Objective-C:

目标-C

self.tableHeightConstraint.constant = CGFLOAT_MAX;
[self.tableView reloadData];
[self.tableView layoutIfNeeded];
self.tableHeightConstraint.constant = self.tableView.contentSize.height;

Swift:

斯威夫特

tableHeightConstraint.constant = CGFloat.greatestFiniteMagnitude
tableView.reloadData()
tableView.layoutIfNeeded()
tableHeightConstraint.constant = contentTableView.contentSize.height

Posting this so it will be helpful for others.

发布此信息,以便对其他人有所帮助。

回答by Sohil R. Memon

Finally, I understood you problem and here is the solution of it.

最后,我明白了你的问题,这里是它的解决方案。

I hope you have already done this.

我希望你已经这样做了。

  1. First take put some fix height of UITableView.
  2. Then take the constraint IBOutletof UITableViewHeight.
  3. Then under viewDidLayoutSubviewsmethod you can get the original UITableViewheight after populating the data.
  1. 首先取一些固定高度的UITableView.
  2. 然后取约束IBOutletUITableView高度。
  3. 然后在viewDidLayoutSubviews方法下,您可以UITableView在填充数据后获得原始高度。

Update the below code:

更新以下代码:

override func viewDidLayoutSubviews() {

   constTableViewHeight.constant = tableView.contentSize.height
}

Update:

更新:

self.tableView.estimatedRowHeight = UITableViewAutomaticDimension;

Please check this.

请检查这个。

回答by Tzegenos

By setting the estimatedRowHeightto zeroduring table view initialisation and by adding the following code to viewDidLayoutSubviewsworked for me!

通过设置estimatedRowHeight表视图初始化过程中,并通过添加以下代码来viewDidLayoutSubviews为我工作!

tableView.reloadData()
tableView.layoutIfNeeded()
tableView.constant = tableView.contentSize.height

回答by flo bee

All the solutions above weren't working for my case. I ended up using an observer like this:

以上所有解决方案都不适用于我的情况。我最终使用了这样的观察者:

self.tableView.addObserver(self, forKeyPath: "contentSize", options: .new, context: nil)

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    if let obj = object as? UITableView {
        if obj == self.tableView && keyPath == "contentSize" {
            if let newSize = change?[NSKeyValueChangeKey.newKey] as? CGSize {
                self.tableView.frame.size.height = newSize.height
            }
        }
    }
}

回答by Daniil Chuiko

for swift just use

快速使用

tableView.invalidateIntrinsicContentSize()
tableView.layoutIfNeeded()

after reloadData() and

在 reloadData() 和

tableView.contentSize.height

will works perfect. Example on medium

将完美运行。 介质示例

回答by Bharat Modi

You can try two things,

你可以尝试两件事,

  1. Call below method just after some seconds of delay after tableView reloads completely.

    - (void)adjustHeightOfTableview
    {
      dispatch_async(dispatch_get_main_queue(), ^{
    
      [self.tableView reloadData];
    
      //In my case i had to call this method after some delay, because (i think) it will allow tableView to reload completely and then calculate the height required for itself. (This might be a workaround, but it worked for me)
      [self performSelector:@selector(adjustHeightOfTableview) withObject:nil afterDelay:0.3];
      });
    }
    
  2. When you call above method do not return estimatedHeightForRow,

    /*
    -(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
       return 44;
    } 
    */
    
    -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
       return UITableViewAutomaticDimension;
    }
    
  1. 在 tableView 完全重新加载后的几秒钟延迟后调用下面的方法。

    - (void)adjustHeightOfTableview
    {
      dispatch_async(dispatch_get_main_queue(), ^{
    
      [self.tableView reloadData];
    
      //In my case i had to call this method after some delay, because (i think) it will allow tableView to reload completely and then calculate the height required for itself. (This might be a workaround, but it worked for me)
      [self performSelector:@selector(adjustHeightOfTableview) withObject:nil afterDelay:0.3];
      });
    }
    
  2. 当你调用上面的方法不返回estimatedHeightForRow,

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

Just give it a try, it could help you get the problem.

试试看,它可以帮助您解决问题。

回答by Stefan S

For me the solution was to just set the estimatedRowHeightto a value larger than anything I deemed possible for the data I had to display.

对我来说,解决方案是将 设置为estimatedRowHeight比我认为可能需要显示的数据更大的值。

For some reason this ensured that the estimatedRowHeightproperty wasn't used to determine the contentSize. I don't display the scroll indicator so it didn't really matter to me that the estimatedRowHeightwas way off.

出于某种原因,这确保了该estimatedRowHeight属性不被用于确定contentSize. 我不显示滚动指示器,所以对我来说这并不重要estimatedRowHeight

回答by Brian Hong

In my case, I don't use tableView's height constraint - using auto layout, top and bottom constraint is set and only bottom constraint changes as it goes into/out of edit mode.

就我而言,我不使用 tableView 的高度约束 - 使用自动布局,设置了顶部和底部约束,并且只有底部约束在进入/退出编辑模式时发生变化。

Tzegenos's answeris modified in this way: 1. add tableView.estimatedRowHeight = 0in viewDidLoad() 2. add the following:

Tzegenos 的答案是这样修改的: 1.tableView.estimatedRowHeight = 0在 viewDidLoad() 中添加 2. 添加以下内容:

override func viewDidLayoutSubviews() {

    // 60 is row's height as set by tableView( cellRowAt )
    // places is of type [String] to be used by tableView
    tableView.contentSize.height = 60 * CGFloat(places.count)
}

回答by nikans

You may as well subclass the UITableViewand call whomever you want (i.e. it's container view) from it's layoutSubviews()where you definitely have a proper contentSize.

您不妨子类UITableView,并打电话给你想要的任何人(即它的容器视图)从它layoutSubviews(),你肯定有一个适当的contentSize