Dynamically Sized Table View Header or Footer Using Auto Layout
I’m trying to support Dynamic Type everywhere I can in my new app. Auto Layout and self sizing table view cells (buggy as they are) makes that a lot easier for the most part. Still, there’s other places that just setting up constraints and changing the font size of a label isn’t enough. The one I’ve just dealt with is a table view header (UITableView().tableHeaderView
) with text in it. If I do nothing but set up my constraints and set the header view, the font size changing will just cause extra space to appear or my text to get cut off.
The solution was to override UIViewController().viewDidLayoutSubviews()
, get the proper size of the header view based on it’s constraints, set the frame on the header, and reset it as the table header view.
It took me a little while to figure this out, so here’s what I did:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
// Dynamic sizing for the header view
if let headerView = tableView.tableHeaderView {
let height = headerView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize).height
var headerFrame = headerView.frame
// If we don't have this check, viewDidLayoutSubviews() will get
// repeatedly, causing the app to hang.
if height != headerFrame.size.height {
headerFrame.size.height = height
headerView.frame = headerFrame
tableView.tableHeaderView = headerView
}
}
}