Sticky Footers with UITableView

The Problem

Last week, I had to implement sticky footers in a table view. Sticky footers are where the footer comes at the end of all the table contents, but if the contents are such that the scrollable content height of the table view is less than the height of the view, the footer will still appear at the bottom of the view.

Non Sticky Footer

A non-sticky footer

A sticky footer

A sticky footer

I searched for a solution to this, but all I found were solutions where the footer was always at the bottom of the view. That’s pretty easy to solve. You just use a UIViewController and put a UITableView and your footer view into the view controller’s view, lay it out properly and you’re good to go. In this scenario, the footer never scrolls and is always visible. That’s not the kind of sticky footer I needed.

The Solution

The solution I came up with was to stick my footer view into another view that I used as the UITableView’s footer. Let’s call it the main footer view. You then resize this main footer view depending on the scrollable content of the table. If the scrollable content height is greater than the tables view’s visible height then no need to do anything. The main footer view and my footer view are the same size. However, if the content height is less than the visible height then you just resize the main footer view to occupy the remaining space.

The Code

First, I added a propery to my UITableViewController subclass:

@property (nonatomic) BOOL footerNeedsLayout;

Then I overrode viewDidLayoutSubviews:

What this does is recreate the footer and position it after everything has been laid out. What this means is that whenever your data changes and before you call reloadData on the table you should set footerNeedsLayout to YES.

This could have been done with programmatic constraints and let AutoLayout take care of it, but I chose to do it this way as it seemed to be a simpler solution and easier to get done in the time constraints I was under. Plus I wanted the compliance footer to be a reusable component and didn’t want to duplicate the UI all over the storyboard for the app.

Adding the footer works like this:

Notice that we do set the autoresizing masks of the compliance footer and the main footer so that AutoLayout will generate the correct constraints.

Finally, here’s the code to compute the frame for our main footer view:

We just compute the visible space of the table view (its height – its content insets). If the height of the table view’s content is less than the visible space – the footer height then we adjust the footer to fill up the empty space. Otherwise we leave the footer alone.

It wasn’t as hard as a thought it would be. A better solution would be to use layout constraints in such a way that the footer wouldn’t have to be constantly recreated and repositioned whenever the data changes.

Back to WordPress

You’ve probably noticed that my blog has changed again. I’ve moved back to WordPress from Octopress. I could never find a plugin for Octopress that did image captions right. I spent way too much time on it and just decided to use something that just worked. I looked at a lot of static blogging engines and they all had their issues.

With WordPress, I have to use the web based editor, but it works and their is a lot of plugins and support behind it. I have better things to spend my time on. To make things better, I think I’ll try Desk. I’ve also installed the Markdown plugin, so I can continue to use it.

This has also got me thinking. Wouldn’t be nice if there was a Mac app that provided a nice writing environment (with Markdown of course), and then would generate your static website, without having to use the command-line or be a programmer? There used to be an app from Fog Creek called City Desk that did this. Maybe I’ll create this app.