Is it possible to obtain a dynamic table view section header height using Auto Layout?

This is possible. It is new right alongside the dynamic cell heights implemented in iOS 8.

It's very simple. Just add this in viewDidLoad:

self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension;
self.tableView.estimatedSectionHeaderHeight = 25;

Then override viewForHeaderInSection and use Auto Layout to constrain elements in your view as seen fit. That's it! No need to implement heightForHeaderInSection. And actually the sectionHeaderHeight doesn't need not be stated either, I just added it for clarity.

Note that in iOS 11, cells and header/footer views use estimated heights by default. The only thing to do is provide an estimated height to better inform the system what to expect. The default value is UITableViewAutomaticDimension but you should provide a better estimate that is the average height they will be if possible.


This can be accomplished by setting (or returning) the estimatedSectionHeaderHeight on your table view.

If your section header is overlapping your cells after setting estimatedSectionHeaderHeight, make sure that you're using an estimatedRowHeight as well.

(I'm adding this answer because the second paragraph contains an answer to an issue that can be found after reading through all of the comments which some might miss.)


Got stuck in the same issue where header was getting zero height untill and unless I provide a fixed height in the delegate for heighForHeaderInSection.

Tried a lot of solutions which includes

self.tableView.sectionHeaderHeight = UITableView.automaticDimension
self.tableView.estimatedSectionHeaderHeight = 73

But nothing worked. My cell were using proper autolayouts too. Rows were changing their height dynamically by using the following code but section header weren't.

self.tableView.estimatedRowHeight = 135
self.tableView.rowHeight = UITableView.automaticDimension

The fix is extremely simple and weird too but I had to implement the delegate methods instead of 1 line code for the estimatedSectionHeaderHeight and sectionHeaderHeight which goes as follows for my case.

func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return UITableView.automaticDimension
}

func tableView(_ tableView: UITableView, estimatedHeightForHeaderInSection section: Int) -> CGFloat {
    return 73
}