Dynamic UITableView height

  1. Subclass your UITableView to override the intrinsicContentSize to be its contentSize, like this:

    override var intrinsicContentSize: CGSize {
        return contentSize
    }
    
  2. Then use automatic row heights for your table, so your exampleViewController's viewDidLoad would have:

    tableView.estimatedRowHeight = 44
    

    And the UITableViewDelegate function:

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableViewAutomaticDimension
    }
    
  3. When you receive data from your API and reload your table, just call:

    tableView.invalidateIntrinsicContentSize()
    

    This will tell your table to resize itself to the same size as its contents (because of the override), and move your bottom image as needed.


If your storyboard throws an error saying that your UIScrollView has an ambiguous height because there's no height constraint on the UITableView, select your UITableView and give it a placeholder intrinsic size in the Size Inspector.


The answers using the subclassing technique are incomplete. You should also override layoutSubviews() like this.

public class DynamicSizeTableView: UITableView
{
    override public func layoutSubviews() {
        super.layoutSubviews()
        if bounds.size != intrinsicContentSize {
            invalidateIntrinsicContentSize()
        }
    }

    override public var intrinsicContentSize: CGSize {
        return contentSize
    }
}