read

Using UITableViewHeaderFooterView in Storyboard/Interface Builder is not easy because:

  • It is not well documented
  • There are a number of ways
  • Things (iOS) change, and break..

For example, this highest voted answer in 2012 does not work well anymore (the section could disappear on reload).

As of writing, this guide is good for iOS 9.

And we will be using awesome swift code :)

Step 1: Subclass UITableViewHeaderFooterView

Add your custom class. We call it TableSectionHeader and it has only a UILabel in it. You will probably add other subviews/IBOutlets to it.

class TableSectionHeader: UITableViewHeaderFooterView {
    @IBOutlet weak var titleLabel: UILabel!
}

Step 2: Create the Nib

Add a Nib (Add new > User Interface > View), and customize it as follows:

  • Change the class to TableSectionHeader
  • In the “Table Section Header” view, make sure the background color is default. This is to avoid the warning Setting the background color on UITableViewHeaderFooterView has been deprecated.
  • Add a View. This is a container and MUST be there to contain all the other subviews.
  • Add the title UILabel, and connect this to the IBOutlet in the class file. If you have other subviews/outlets, do the same.

Step 3: Register the Nib

In your view controller viewDidLoad, you need to register the nib with a reuse identifier.

let nib = UINib(nibName: "TableSectionHeader", bundle: nil)
tableView.registerNib(nib, forHeaderFooterViewReuseIdentifier: "TableSectionHeader")

Step 4: Implement viewForHeaderInSection

func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    // Here, we use NSFetchedResultsController
    // And we simply use the section name as title
    let currSection = fetchedResultsController.sections?[section]
    let title = currSection!.name

    // Dequeue with the reuse identifier
    let cell = self.tableView.dequeueReusableHeaderFooterViewWithIdentifier("TableSectionHeader")
    let header = cell as! TableSectionHeader
    header.titleLabel.text = title

    return cell
}

The gist is using dequeueReusableHeaderFooterViewWithIdentifier to get back the header section cell. You can then configure the cell similarly to how you do it for normal row cells.

That’s it!

The Other Ways

This guide is for using Storyboard/Interface Builder to create your custom header/footer.

If all you want is to change the background color and text color, then you could simply override willDisplayHeaderView as described in elicere blog.

You can also refer to Apple sample code (in Objective-C)

Pitfall: Does not play well with Autolayout

One problem with UITableViewHeaderFooterView is that it does not play very well with autolayout.

It is possible to have autolayout, but as of iOS 11, it seems like Apple has a bug. You might encounter this error:

Unable to simultaneously satisfy constraints… ‘UIView-Encapsulated-Layout-Height’ …

The problem is that UITableView does something to the header/footer view, encapsulating it, and creating a required (priority 1000) constraint on the height.

And this height will be slightly taller than your layout (maybe to cater for the separator?). Anyway, the height does not match.

The workaround is that your height/bottom/vertical constraint has to be lowered. eg. 999

This workaround is effective for UITableViewCell too.


Image

@samwize

¯\_(ツ)_/¯

Back to Home