Swift - how to make custom header for UITableView?
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
A UITableView section header is not a special magic object. In UIKit it is just a view the table asks you to provide, so the main decision is whether you need a quick static header or a reusable header class with its own layout and behavior. For prototypes, returning a plain UIView is fine. For production screens, a UITableViewHeaderFooterView subclass is usually the cleaner and more scalable option.
Start With the Right Delegate Methods
Per-section headers are created through tableView(_:viewForHeaderInSection:). Their size is usually supplied by tableView(_:heightForHeaderInSection:), or by automatic dimension if you configure the table correctly.
A minimal header can be built inline:
This pattern works, but it becomes awkward once the header gains icons, buttons, or state.
Prefer UITableViewHeaderFooterView for Real Screens
A reusable header view makes the codebase easier to maintain. It keeps header layout in one place, supports reuse, and avoids rebuilding the whole view hierarchy each time the table scrolls.
Register it once and dequeue it in the delegate:
That pattern is the UIKit equivalent of a reusable cell. The controller decides what data to show. The header manages its own appearance and controls.
Use Auto Layout Instead of Manual Frames
Many header bugs come from using fixed frames after the layout stops being fixed. A label that fits in English may clip in another language. A hard-coded height may fail when Dynamic Type is enabled. Auto Layout is the safer default once the header contains more than one element.
If you want self-sizing headers, enable estimated heights and return UITableView.automaticDimension.
For this to work well, the header view must have constraints that fully describe its vertical size. In practice that means pinning subviews to the top and bottom of contentView, not only centering them vertically.
Distinguish Section Headers From tableHeaderView
A common source of confusion is mixing section headers with the table's one top banner. tableHeaderView is a single view shown once at the top of the table. viewForHeaderInSection is called for each section. If you want a profile card above the whole list, use tableHeaderView. If you want a label such as “Favorites” above each group of rows, use section headers.
That distinction matters because the APIs and sizing behavior are different. Developers often spend time debugging the wrong header type because the names sound similar.
Keep Interaction Flow Simple
Interactive headers are normal. Filters, expand buttons, sort controls, and disclosure actions all fit well in a header. The important part is keeping the responsibilities separate. The header should not mutate the data source directly. Let it expose a closure or delegate callback, then let the controller update the model and reload the table.
That approach avoids hidden coupling and makes the header reusable in other screens.
Common Pitfalls
- Building a complex hierarchy inline inside
viewForHeaderInSectioninstead of moving it into a reusable header class. - Forgetting to register the
UITableViewHeaderFooterViewsubclass before dequeuing it. - Using fixed frames for text that needs Dynamic Type or localization support.
- Confusing
tableHeaderViewwith per-section headers and debugging the wrong API. - Putting data-source mutations inside the header view instead of sending actions back to the controller.
Summary
- A custom
UITableViewheader is just a view returned by the table delegate. - Inline
UIViewheaders are acceptable for simple cases, but reusable header classes scale better. - '
UITableViewHeaderFooterViewis the preferred UIKit type for maintainable section headers.' - Auto Layout makes dynamic content and self-sizing headers much more reliable.
- Keep the header focused on presentation and route user actions back to the view controller.
Related reading
- Swift - How to remove a decimal from a float if the decimal is equal to 0?
- Swift - How to remove a decimal from a float if the decimal is equal to 0?
- Swift - How to replace characters in a String?
- Swift - Integer conversion to Hours/Minutes/Seconds
- Swift - Integer conversion to Hours/Minutes/Seconds
- Swift - Sort array of objects with multiple criteria
- Swift - specialized _VariantDictionaryBuffer.ensureUniqueNativeBufferInt
- Swift - UIButton with two lines of text
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack 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.