Applications open until spots fill up - Apply now.

Improving the Design: Post Headers

Improving the Design: Post Headers

May 26, 2015

This and the following steps will focus primarily on improving the design of Makestagram. One of the missing visual features are headers above every post that show the username and when the post was created. Here's what the final timeline of Makestagram will look like, when it includes that feature:


In this step, we will add these headers to every post. The header will be a second type of UITableViewCell that we will configure in Interface Builder.

Creating the Header Cell

Let's start by setting that cell up.

Create a new UITableViewCell for the Post's header, as shown in the video below:

Note that in the video, the clock image was called Time. In your app, it will be called Clock.

Throughout the instructions I have been updating the frames of our views by using the ⌘⌥= shortkey. To make sure that your frames are up to date, select any view in the storyboard, then select Update Frames as shown below:


Next, we need to define an identifier for that new table view cell so that we can reference it in code.

Set the identifier of the cell to PostHeader: image

Just as with the post cell we don't want this cell to be selectable; we are not using the header cell for user interaction, instead we only want to display information.

Disable selection for the header cell: image

And finally, the header should have a solid white background.

Set the background color of the header cell to white: image

We will also need a new Swift class for this cell. That will allow us to create references to the two labels on the header. We can then use these references to display the username of the creator of a post along with the creation date.

Setting up Code Connections

Create a new class PostSectionHeaderView and make it a subclass of UITableViewCell.

Now we'll connect our class and the cell in Interface Builder and create referencing outlets for both labels.

Set the Custom Class of the new table view cell:


Now we can create the referencing outlets.

Add referencing outlets for both labels:


Now our Interface Builder setup is complete and we can start writing some code.

Implementing the Post Cell Header

The code for the header cell will be very simple. We want it to accept a Post object and then display the information contained in it. For now, we will skip the time information and only display the username. In the next step we'll use a third-party library which will help us displaying how long ago a post has been created.

Change the content of the PostSectionHeaderView.swift file to look as following:

import UIKit

class PostSectionHeaderView: UITableViewCell {

  @IBOutlet weak var postTimeLabel: UILabel!
  @IBOutlet weak var usernameLabel: UILabel!

  var post: Post? {
    didSet {
      if let post = post {
        usernameLabel.text = post.user?.username

As you can see: compared to the code we've written so far, this is not too exciting! The more interesting part is presenting this new header cell above every single post in our table view.

Displaying the Post Cell Header

Luckily, displaying our header cells is not too complicated. Apple has built this functionality into UITableView.

The UITableView divides its content into sections and rows. Currently our table view has exactly one section, with all posts displayed as individual rows within that section.

Each section in a UITableView can have a header view. This means we could easily display one header view for our one section.

But how can we display a header for each post?

The trick is to change the structure of our data in the table view. Instead of displaying each post as a row, we will display each post as a section. This way we will be able to provide an individual section header for each post.

Essentially we are swapping the meaning of rows and sections - this requires some changes to our TimelineViewController.

Let's first update the two methods that define the amount of rows and sections!

Change the implementation of numberOfSectionsInTableView(_:) and tableView(_: UITableView, numberOfRowsInSection) to look as following:

func numberOfSectionsInTableView(tableView: UITableView) -> Int {
  return self.timelineComponent.content.count

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  return 1

All we are doing is swapping the implementation of both of these methods. We now have a section for each post, that contains exactly one row. Before the change we had exactly one section that contained one row for each post.

Now that sections, and no longer rows, are mapped to posts, we also need to change our implementation of tableView(_:, cellForRowAtIndexPath).

Change the tableView(_:, cellForRowAtIndexPath) method to look as following:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
  let cell = tableView.dequeueReusableCellWithIdentifier("PostCell") as! PostTableViewCell

  let post = timelineComponent.content[indexPath.section]
  post.fetchLikes() = post

  return cell

We now select which post should be displayed based on indexPath.section instead of indexPath.row.

We need to apply the same change to the tableView(_:, willDisplayCell:, forRowAtIndexPath) method!

Change the implementation of tableView(_:, willDisplayCell:, forRowAtIndexPath) to look as following:

func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {


Now we are informing the timelineComponent about which post is currently being displayed by sending it the indexPath.section instead of the indexPath.row.

At this point we have successfully swapped the meaning of rows and sections throughout the entire TimelineViewController. Now we can add the code that will display our section headers.

We need to implement two methods of the UITableViewDelegate protocol. One defines the height of our header, the other is responsible for providing the view that should be displayed.

Add the following two methods to the UITableViewDelegate extension of the TimelineViewController:

func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
  let headerCell = tableView.dequeueReusableCellWithIdentifier("PostHeader") as! PostSectionHeaderView

  let post = self.timelineComponent.content[section] = post

  return headerCell

func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
  return 40

The implementation for providing header cells is almost identical to the code that provides the post cells - there aren't any new concepts in these few lines. We dequeue a PostHeader cell, fetch the corresponding post and assign it to the cell. The cell then displays the username based on the user associated with the provided post.

Time to run the app and try this feature out. Ideally it should look similar to this: image

Awesome! Now this app looks very similar to a famous photo sharing app!


In this step, you learned more about how rows and sections compose the content of a table view. You have also learned how to display section headers.

In the next step we will improve these headers, by displaying the amount of time that has passed since a post has been created. You will also learn how to install a third-party library to help us with that feature.


If you have feedback on this tutorial or find any mistakes, please open issues on the GitHub Repository.

Summer academy

An iOS Development Summer Course

Design, code and launch your own app. Locations across the USA and Asia

Find your location

Product College

A computer science college

Graduate into a successful career as a founder or software engineer.

Learn more