Expandable and dynamic sized Table Header View and Table Footer View

A quick look at how to dynamically expand and resize a UITableView’s header and footer view.

Thomas Asheim Smedmann
5 min readAug 23, 2022
Expandable and dynamic sized Table Header View and Table Footer View.

Images and facts about Luke Skywalker were found at https://starwars.fandom.com/wiki/Luke_Skywalker, and https://swapi.dev/.

UITableView is one of our favourite components when making iOS apps with UIKit. It’s perfect when you need to display a list of content. And it comes with the possibility to add a header and a footer to the top and bottom of your list (UITableView.tableHeaderView and UITableView.tableFooterView). But it has its quirks…

The UITableView has been around since ancient days of iOS, and rely on its header and footer view to manually set their own size (their frame’s height). So even though you are using Auto Layout Constraints to define the internal layout of your UITableView’s header and footer view, you still need to manually set the height of these views. The width will be forced by the UITableView to be equal to the UITableView’s width. This will ensure that the header and footer view have the proper width to fit inside the UITableView. All this makes the UITableView’s header and footer view somewhat cumbersome to work with.

This is all mentioned in the documentation of UITableView.tableHeaderView and UITableView.tableFooterView.

In this article we’ll take a look at how you can dynamically resize your UITableView’s header and footer view without too much of a hassle.

If you just want to get your hands on some example code right away, you can find the complete source code for the example used in this article here: https://github.com/thomsmed/ios-examples/tree/main/DynamicTableHeaderView

Key takeaways

Note: You might want to animate the offset of your footer view along any changes to your header’s height, or else the UITableView will just instantly update the footer view’s offset.

An example to go by

As an example, we’ll create a simple application to showcase our favourite Star Wars hero — Luke Skywalker!

The application will have a list of facts about our hero, and an image in the header that expands when tapped on. The footer will hold an expandable horizontal list with information about all the films Luke appears in.

In the remainder of this article, we’ll only look at key parts of what we want to achieve (dynamic sized header view and footer view). So any details about how the app’s UI is constructed is omitted.

You can find the complete source code for the example app used in this article here: https://github.com/thomsmed/ios-examples/tree/main/DynamicTableHeaderView

Images and facts about Luke Skywalker were found at https://starwars.fandom.com/wiki/Luke_Skywalker, and https://swapi.dev/.

Setting the height of the UITableView’s header and footer view

UITableView will force its own width onto its header and footer view, but respect their height, when laying out its subviews (header view and footer view + its UITableViewCells). So the UITableView expect us to manually set the height of its header and footer view.

A neat place to do just that is in the layoutSubviews() method of your header and footer view.

Note: Normally layoutSubviews() is intended to be used to manually set the frames of subviews, and not the view it self. So as an alternative, one could have the parent UITableView / UITableViewController do the resizing at appropriate times.

After adding your header and footer views to the UITableView, you should call UITableView.layoutIfNeeded().

Dynamically resize the UITableView’s header and footer views

Dynamically change the size of the UITableView’s header view.

When you do layout changes to a UITableView’s header or footer view (typically by changing some Auto Layout Constraints), you need to tell the UITableView about these changes so that it can include them in a layout update. The way to do this is to wrap your layout changes inside a call to UITableView.performBatchUpdates(…).

By default, the UITableView will animate any changes to the position of its UITableViewCells, so if you change the height of the header or footer view, the UITableViewCells will be animated to their new position. The UITableView does not — however — apply this animation to changes done to its header and footer view, so you might want to wrap it all inside a call to UIView.performWithoutAnimation(…). That way none of the layout changes will be animated.

Alternatively, you could just animate changes to the header and footer view along the UITableView’s default animation.

Animate size changes

Animate changes to the table view’s header view.

Changes to your UITableView’s header and footer views can easily be animated by e.g. wrapping them in a call to UIView.animate(…) (inside a call to UITableView.performBatchUpdates(…)).

A good idea is to set the duration of your animation(s) to approximately the same as the UITableView’s default animation (seems to be around 0.3 seconds).

Having both a header view and a footer view

Expandable and dynamic sized Table Header View and Table Footer View.

To add and dynamically resize a footer view, you can use the same strategies as for adding and resizing a header view. One tiny thing to notice, though, is that when you animate size changes to the header view that affect the position of the footer view (e.g. shrinking the height of the header view), you might want to animate the footer view’s position change as well (since there is no default animation applied by the UITableView). Otherwise the footer view would just jump straight into its new position.

That’s it!

Hopefully this article has shed some light on how to work with UITableView’s header view and footer view, and provided some useful tips on how to dynamically resize them.

The complete source code for the example app used in this article can be found here: https://github.com/thomsmed/ios-examples/tree/main/DynamicTableHeaderView

Happy coding! 🙌

--

--