UITableView content size while using auto-layout

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 IBOutlet of UITableView Height.
  3. Then under viewDidLayoutSubviews method you can get the original UITableView height after populating the data.

Update the below code:

override func viewDidLayoutSubviews() {

   constTableViewHeight.constant = tableView.contentSize.height
}

Update:

self.tableView.estimatedRowHeight = UITableViewAutomaticDimension;

Please check this.


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.

Objective-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.


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