How to create UITableView with sections

create UITableView with sections - Swift Tutorial

Introduction to UITableView with sections

In this tutorial, we will create UITableView with sections. Or in other words a grouped UITableView. Sections in UITableView are commonly used in cases where, we group items. In this tutorial, we will create sections in UITableView according to following condition

  • Developers grouped according to their job role. Example iOS developers, android developers and so on.


  • Xcode 11.0

Steps to create UITableView with sections

Step 1: Create a single view application project.

Step 2: Open ViewController.swift and create an IBOutlet for UITableView, as we will use storyboard and not creating controls programmatically. Also we will create an array named expertise, act as our data-source for UITableView and, contains Dictionary as its elements.

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var tblCoders: UITableView!
    var expertise = [Dictionary<String, Any>]()

Step 3: Open Main.storyboard and drag UITableView on to the view and connect outlet for UITableView created in step 2.

Creating UITableViewCell

Step 4: Create a new UITableViewCell class, and name it “CoderInfoCell”. To create UITableViewCell class, tap on File menu ==> New ==> File ==> Cocoa Touch class ==> chose UITableViewCell as subclass and check mark “Also create xib file.

Step 5: Open “CoderInfoCell.xib”, and drag UILabel on to the view. Add constraint to UILabel as shown below

Constraints for UILabel  - create UITableView with sections
Constraints for UILabel

Step 6: Next, we will create IBOutlet for UILable and create a function that will set text to UILabel.

class CoderInfoCell: UITableViewCell {

    @IBOutlet weak var lblName: UILabel!
    override func awakeFromNib() {
        // Initialization code
    //MARK:- setCoderName
    func setCoderName(_ name: String) {
        self.lblName.text = name

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state

Finally, connect “lblName” IBOutlet, to UILabel in “CoderInfoCell.xib”.

Creating sections in UItableView

Step 7 : Add below code to “ViewDidLoad” function of “ViewController.swift”.

        tblCoders.tableFooterView = UIView(frame: .zero)
        tblCoders.register(UINib(nibName: "CoderInfoCell", bundle: nil), forCellReuseIdentifier: "CoderInfoCell")
        tblCoders.estimatedRowHeight = 60.0
        tblCoders.dataSource = self
        tblCoders.delegate = self

In above code, we register our custom cell class with UITableView. Set estimated row height to 60.0. Called a function named, “createDatSource” that will add values to “expertise” array (our data-source).

Data-Source array for UITableView with sections

  func createDatSource() {
        expertise.append(["title": "iOS", "value": ["Tom", "John", "Moody"]])
        expertise.append(["title": "Android", "value": ["Reema", "Raze", "Jack","Joody"]])
        expertise.append(["title": "ROR", "value": ["Majed", "Ali", "Ryan"]])
        expertise.append(["title": "Python", "value": ["Jake", "Riyadh", "Mark"]])
        expertise.append(["title": "PHP", "value": ["Jerry", "Alex", "Cyril","Rohn","ROB","John","Rahul"]])


In above function, we created a dictionary, with key
1) title :- Will act as section title
2) value :- will act as rows for section as its an array of string

Implementing UITableViewDataSource and UITableViewDelegate

Below is the code that implements, datasource and delegate methods for UITableView.

extension ViewController: UITableViewDataSource {
    func numberOfSections(in tableView: UITableView) -> Int {
        return expertise.count
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        guard let codersNames = expertise[section]["value"] as? [String] else {
            return 0
        return codersNames.count
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "CoderInfoCell") as! CoderInfoCell
        guard let codersNames = expertise[indexPath.section]["value"] as? [String] else {
            return cell
        return cell
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let view = UIView(frame: CGRect(x: 0.0, y: 0.0, width: tblCoders.frame.size.width, height: 50.0))
        view.backgroundColor = .systemGreen
        let titleLabel = UILabel(frame: CGRect(x: 15.0, y: 0.0, width: view.frame.size.width, height: 50.0))
        titleLabel.textColor = .white
        titleLabel.font = UIFont.boldSystemFont(ofSize: 16.0)
        if let title = expertise[section]["title"] as? String {
            titleLabel.text = title
        return view
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 50.0

extension ViewController: UITableViewDelegate {
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableView.automaticDimension

Though above code is self explanatory, let us summarize it.

  • numberOfSections :- equals to our array count, as we wan to display number of section equal to our array(data-source) elements.
  • numberOfRowsInSection :- here we get the rows for section. As our data-source (expertise) contains array for key “value”, which makes our job easier.
  • cellForRowAt :- here we will list out the names of developers, again we using array for key “value” in our expertise data-source.
  • viewForHeaderInSection :- need to implement so that we can display section for our UITableView.
  • heightForHeaderInSection :- set UItableView section height.
  • heightForRowAt :- will set height for our section rows

Where to go from here

In this tutorial, we learned about how to create section for UITableView in swift. Download code for this tutorial from code section.

Download source code for UITableView with sections

Source code: