UITableView
iOS Development
Storyboard
Footer
Xcode

How to add a footer to a UITableView in Storyboard

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

In UITableView, there are two different footer concepts: a footer for each section and one footer view for the whole table. If your goal is a single view at the bottom of the table and you are designing the UI in Storyboard, the usual solution is to build a UIView in Storyboard and assign it to tableFooterView in code.

This distinction matters:

  • 'tableFooterView is one view for the whole table'
  • 'viewForFooterInSection creates a footer per section'

If you want a static message, button bar, loading indicator, or summary at the end of the entire table, tableFooterView is the correct API.

The common Storyboard pattern is:

  1. add a plain UIView to the scene
  2. design its contents with labels, buttons, or stack views
  3. connect it as an outlet
  4. assign it to tableView.tableFooterView

Example outlets:

swift
1import UIKit
2
3final class ItemsViewController: UIViewController {
4    @IBOutlet private weak var tableView: UITableView!
5    @IBOutlet private weak var footerContainerView: UIView!
6}

Then attach it in viewDidLoad:

swift
1override func viewDidLoad() {
2    super.viewDidLoad()
3    tableView.tableFooterView = footerContainerView
4}

That is the key step. The view can be created in Storyboard, but the table still needs the explicit assignment.

tableFooterView does not automatically resize itself from constraints the way normal subviews do. If your footer is designed with Auto Layout content, you often need to force layout and then update the frame height:

swift
1override func viewDidLayoutSubviews() {
2    super.viewDidLayoutSubviews()
3    updateFooterSize()
4}
5
6private func updateFooterSize() {
7    guard let footer = tableView.tableFooterView else { return }
8
9    footer.setNeedsLayout()
10    footer.layoutIfNeeded()
11
12    let height = footer.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize).height
13
14    if footer.frame.height != height {
15        footer.frame.size.height = height
16        tableView.tableFooterView = footer
17    }
18}

This is the part many developers miss. Without it, a footer that looks fine in Storyboard can appear with the wrong height at runtime.

If the footer should appear once per section instead of once for the entire table, implement the delegate methods instead:

swift
1func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
2    let label = UILabel()
3    label.text = "End of section \\(section)"
4    label.textAlignment = .center
5    return label
6}
7
8func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
9    44
10}

This is not the same feature as tableFooterView, even though both are called footers.

That distinction matters in Storyboard-driven apps because the visual design can look similar while the lifecycle and sizing behavior are completely different.

Common Pitfalls

The biggest mistake is building a footer view in Storyboard and assuming the table will use it automatically. It will not until you assign it to tableFooterView.

Another common issue is expecting Auto Layout to size tableFooterView automatically. In practice, you often need to recalculate the frame height after layout.

It is also easy to confuse table footers with section footers and wire up the wrong API for the UI you actually want.

In data-driven screens, it is also worth remembering that footer content may need to be refreshed when the table's data or layout changes, not just once in viewDidLoad.

Summary

  • Use tableFooterView for one footer at the bottom of the entire table.
  • Build the footer in Storyboard if you want, but assign it in code.
  • Recalculate the footer height if Auto Layout content is involved.
  • Use section-footer delegate methods only when you need one footer per section.
  • Most footer bugs come from mixing up these two footer models or forgetting the runtime assignment step.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.