0
votes

I'm making an app with Swift, and I've come across a problem: I have a system where people can make "posts", and comment on those "posts".

In order to display this, I have a UITableViewController subclass that has the post as the header, and the comments in the cells.

Now I have a screen that needs to list these posts. Ideally, I want to have each post with its comments in a single cell.

This would require embedding the UITableViewController subclass (let's call it PostTableViewController) inside a cell of another UITableViewController.

The problem is, I don't want each of these ProfileTableViewControllers scrolling inside their cells. I need to turn scrolling off on the tableViewController, and make its height extend to fit its entire content.

I have looked at the answers on this post, but I'm still having problems. It's unclear at the moment whether the tableView is resizing correctly, because the height of the ProfileTableViewController within its respective cell is always 0. I can see part of it if I manually set a constant height constraint, but I want it to auto-resize to fit the tableView.

My current constraint setup is:

    //dateView is another view in my tableViewCell
    profileViewController.view.topAnchor.constraint(equalTo: dateView.bottomAnchor).isActive = true
    profileViewController.view.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
    profileViewController.view.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true
    profileViewController.view.widthAnchor.constraint(equalTo: self.widthAnchor).isActive = true

    profileViewController.view.bottomAnchor.constraint(equalTo: profileViewController.tableView.tableFooterView!.bottomAnchor).isActive = true
    profileViewController.tableView.topAnchor.constraint(equalTo: profileViewController.view.topAnchor).isActive = true

    self.bottomAnchor.constraint(equalTo: homeViewController.view.bottomAnchor).isActive = true

So how can I make the tableView automatically fit its content, and also set up constraints so that the tableViewCell will autoresize to the tableView?

NOTE (1): My interface is completely code; no storyboard relevant to this situation

NOTE (2): The content of the ProfileTableViewControllers is dynamic, so the constraints need to update when it changes.

3

3 Answers

1
votes

For those who are looking at this in the future, what I ended up doing was separating the posts into tableView sections, rather than cells, and then adding one cell for the profileTableViewController, and cells for the comments underneath it.

0
votes

To have the tableview adjust its height to its contents height you will need to set up an additional height constraint and update it on every data reload.

Declare the constraint like this so it can be accessed from other places in the class.

private lazy var heightConstraint: NSLayoutConstraint = {
    let constraint = tableView.heightAnchor.constraint(equalToConstant: 0)
    constraint.isActive = true
    return constraint
}()

and when reloading the data, set the constraint constant value to the tableviews content height

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

calling layoutIfNeeded will be helpful for tableview to determine its content size

and dont forget to turn scrolling off in the tableview

tableView.isScrollEnabled = false
0
votes

In my case, I usually create a custom view which has UITableView inside it and then override intrinsicContentSize property to determine a size of the view. Take a look at the following code.

override var intrinsicContentSize: CGSize {
    self.tableView.layoutIfNeeded()
    let size = self.tableView.contentSize
    print("size = \(size)")
    return size
}

As you use AutoLayout System, that way probably works well in your code.

If you use UICollectionView, collectionViewContentSize property can be used instead of contentSize.