How do I set the height of tableHeaderView (UITableView) with autolayout?

You need to use the UIView systemLayoutSizeFittingSize: method to obtain the minimum bounding size of your header view.

I provide further discussion on using this API in this Q/A:

How to resize superview to fit all subviews with autolayout?


I've found an elegant way to way to use auto layout to resize table headers, with and without animation.

Simply add this to your View Controller.

func sizeHeaderToFit(tableView: UITableView) {
    if let headerView = tableView.tableHeaderView {
        let height = headerView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize).height
        var frame = headerView.frame
        frame.size.height = height
        headerView.frame = frame
        tableView.tableHeaderView = headerView
        headerView.setNeedsLayout()
        headerView.layoutIfNeeded()
    }
}

To resize according to a dynamically changing label:

@IBAction func addMoreText(sender: AnyObject) {
    self.label.text = self.label.text! + "\nThis header can dynamically resize according to its contents."
}

override func viewDidLayoutSubviews() {
    // viewDidLayoutSubviews is called when labels change.
    super.viewDidLayoutSubviews()
    sizeHeaderToFit(tableView)
}

To animate a resize according to a changes in a constraint:

@IBOutlet weak var makeThisTallerHeight: NSLayoutConstraint!

@IBAction func makeThisTaller(sender: AnyObject) {

    UIView.animateWithDuration(0.3) {
        self.tableView.beginUpdates()
        self.makeThisTallerHeight.constant += 20
        self.sizeHeaderToFit(self.tableView)
        self.tableView.endUpdates()
    }
}

See the AutoResizingHeader project to see this in action. https://github.com/p-sun/Swift2-iOS9-UI

AutoResizingHeader