How to show custom table header views in iOS

This post is the continuation of the adding custom cells for tableview, in this post we will see how to configure and setup the header and footer views for a tableview in iOS, these header and footer view generally specifies the area of section’s top and bottom, where you can add some more info for the list of items that you are showing in the tableview not only that you can add interactive elements like for example, adding a button to perform some actions.

If you want to skip to adding footer view you can find the details here, if not lets proceed.

Now in the same project that we have created in adding custom cells for tableview we will continue in that project, since we already learned how to customise the table view cells now lets learn about how to setup and configure custom header and footer views for the tableview. We will achieve the output like below image. Each header with title and footer with “View More” button.

Tableview with custom header and footer views

Now open Main.storyboard and select tableview and change style to Grouped

Change style of table view to “Grouped”

Now add new swift file CustomHeaderView and add below code.


//1.Creating a new class which is sub class of UITableViewHeaderFooterView
class CustomHeaderView: UITableViewHeaderFooterView {
    
    //2.Defined outlets for border view and title label
    @IBOutlet weak var borderView: UIView!
    @IBOutlet weak var headerTitleLabel: UILabel!
    
    override func awakeFromNib() {
        super.awakeFromNib()
    }
}

//3.Reusable protocol for views
extension CustomHeaderView: Reuseable {
    static func reuseID() -> String {
        return String(describing: self)
    }
}

In the above code,

  1. Created a class called CustomHeaderView which is a sub class of UITableViewHeaderFooterView
  2. As per our design we have some holder view and a header title
  3. Confirmed to protocol Reuseable protocol to get the reuse ID

Now let’s add new xib file name it as CustomHeaderView.xib open this file and add a empty view set its size to freeform as shown in below image.

Select the view and set its size to freeform

Once after setting the size to Freeform, we can able to resize the view, drag the view and set to some height and set its class to CustomHeaderView as shown in below image.

Setting up the header view in xib

For the orange colour view you can pin the view to give some gap for top, left and right side of the border view, for the label also set the center Y axis and give leading space as shown in below images.

For Content holder view setup constraints like below,

Setting the constraints for content holder view

For border view setup constraints like below,

Settings constraints for border view

For title label setup constraints like below,

Setting constraints for title label

Now with the above setup our header view is ready with label, now connect the outlets defined in the CustomHeaderView class, with these outlets connected from xib to CustomHeaderView class, we can access them and modify properties dynamically.

Connecting to outlet for borderView
Connecting to outlet for headerTitleLabel

Now let’s add some code to load this header view to table view that is present in ViewController class. Open ViewController.swift file and make the changes like below.

import UIKit

class ViewController: UIViewController {
    //1
    @IBOutlet weak var tableView: UITableView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        registerViewsToTableView()
    }
    
    private func registerViewsToTableView() {
        tableView.register(UINib(nibName: "CustomTableCell", bundle: nil), forCellReuseIdentifier:CustomTableCell.reuseID())
        
        //Register header view for the table
        tableView.register(UINib(nibName: "CustomHeaderView", bundle: nil), forHeaderFooterViewReuseIdentifier: CustomHeaderView.reuseID())
    }
}

    //2
extension ViewController: UITableViewDataSource, UITableViewDelegate {
    func numberOfSections(in tableView: UITableView) -> Int {
        return 5
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return Int.random(in: 3...5)
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: CustomTableCell.reuseID())
        guard let customCell = cell as? CustomTableCell else { return UITableViewCell() }
        return customCell
    }
    
    //Return the header view in this delegate method
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        guard let headerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: CustomHeaderView.reuseID()) as? CustomHeaderView  else { return nil }
        return headerView
    }
    
    //Setting the height for header view
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 50.0
    }
}

In the above code we are simply registering the header view to table view using the method, register(_ nib: UINib?, forHeaderFooterViewReuseIdentifier identifier: String) of the table view, it takes the nib file since we have created a dedicated xib file for table view we can easily create an nib instance with the name of the file CustomHeaderView and the reuse id.

After that we are adding new delegate methods of table view, tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? this method simply asks for the view, in our case we will simply return the instance of the CustomHeaderView, as we already know how table view cells works well by dequeueReusableCell method, same applicable here also, tableView.dequeueReusableHeaderFooterView(withIdentifier: CustomHeaderView.reuseID()) this method simply creates a new instance of the view based on the reuse ID. make sure to register the view before calling this method.

After that we are adding one more delegate method tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat this method we are returning some height for for our header view.

Now with the above code in place run the app you will able to see the table view header as shown in below image.

Table view with custom header view is displayed for each section

Now that our custom header view is displayed, lets make the header view to rounded top left and top right side, lets open CustomHeaderView.swift file and make the changes like below.

//1.Creating a new class which is sub class of UITableViewHeaderFooterView
class CustomHeaderView: UITableViewHeaderFooterView {
    
    //2.Defined outlets for border view and title label
    @IBOutlet weak var borderView: UIView!
    @IBOutlet weak var headerTitleLabel: UILabel!
    
    override func awakeFromNib() {
        super.awakeFromNib()
        
        //1
        self.maskTopOnlyRoundedCorner(for: self.borderView)
    }
    
     //2 method we have added to make the border to rounded corner
    func maskTopOnlyRoundedCorner(for view: UIView) {
        view.layer.cornerRadius = 12.0
        view.layer.maskedCorners = [.layerMaxXMinYCorner, .layerMinXMinYCorner]
    }
}

//3.Reusable protocol for views
extension CustomHeaderView: Reuseable {
    static func reuseID() -> String {
        return String(describing: self)
    }
}

Make sure the outlets are connect to borderView, we have added new method maskTopOnlyRoundedCorner(for view: UIView) this method takes the view as an input and in side this method we are simply setting the view’s cornerRadius and maskedCorners.

Now lets run once again with the above changes you will see the table view with custom header view with nice rounded corner as shown below.

Custom header view with label and rounded top left and top right corners

Nice, now we at this point we have learned how to display custom header view in the next post we will learn about setting up the custom footer view, it is almost same as configuring the the header view, not only that in next post we will see how to handle user interactions from footer view.

You can download sample project from this link.

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *