DEV Community

Law Gimenez
Law Gimenez

Posted on • Originally published at law.gmnz.xyz on

Implementing the expandable cell in iOS UITableView

I’m going to implement below on how to create the expandable UITableView cell for example on iOS stock calendar.

1-K0Xsn4n9Lx2lqpUDNO-xXA

From scratch, create a new project on Xcode. In your main.storyboard remove the default ViewController (delete also the extra unused ViewController.swift file in the project explorer) and drag a new TableViewController.

1-ti0Kq9gWuhSdxOPXvRjDDw

Now that we have our TableViewController set on the storyboard. Let’s create a new Swift file, and call it for example FormTableViewController.swift. And set is as the custom class in your TableViewController.

1-XPDBMIMfwL7hBdvehkUnjQ

1-366I_Aw3939Z5uXtdVX0fg

Now we are all set. We are gonna change the TableView’s Content from Dynamic Prototypes to Static Cells.

After setting it to Static Cells, your TableView will have a default of 3 static cells created.

For this demo it won’t matter how many cells we are going to use.

The secret to this is the proper measurement of a cell. Click on the first cell and change the row height to 250. Our plan is, inside the cell we will have 2 views. The Label which has a height of 50 and DatePicker with a height of 200. A total of 250. On the storyboard, drag a Label and DatePicker on the first cell, setup its constraints and embed our TableViewController with a NavigationController, it should look like the image below.

1-VOvLjMRH2f8Gyu7LmfFvYA

Now let’s start coding. Inside your FormTableViewController you need to override two functions, namely TableView’s didSelectRowAt and heightForRowAt.

import UIKit

class FormTableViewController: UITableViewController {

    private var dateCellExpanded: Bool = false

    override func viewDidLoad() {
        super.viewDidLoad()
        // For removing the extra empty spaces of TableView below
        tableView.tableFooterView = UIView()
    }

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if indexPath.row == 0 {
            if dateCellExpanded {
                dateCellExpanded = false
            } else {
                dateCellExpanded = true
            }
            tableView.beginUpdates()
            tableView.endUpdates()
        }
    }

    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        if indexPath.row == 0 {
            if dateCellExpanded {
                return 250
            } else {
                return 50
            }
        }
        return 50
    }
}

Enter fullscreen mode Exit fullscreen mode

I’m going to explain shortly about the code. The variable dateCellExpanded is a flag to determine if the current cell selected has been expanded or not. Then, after always call tableView.beginUpdates() and tableView.endUpdates() and it will trigger the delegate function of TableView heightForRowAt to determine what height value should we return or not. Yep, it is that simple. Click RUN!

1-_TMKiaY6yEn4iGw2w_vdvQ

Hopefully this demo should give you an idea on how to implement it on your app.

The example project can be found at https://github.com/lawgimenez/expandable-cell-test

Top comments (2)

Collapse
 
alextrashertz profile image
trashertz • Edited

Hi excellent!!, very very concise and synthetic guide, perfect! 👌
I want try this example code for my tableView with 1section and 3 cell, all static, but when tap on first cell, the app open all 3 cells, I want open only firstCell when I tap on this, and open secondCell when tap on this, etc etc
Sorry for my English 😭
u can help me?

Collapse
 
vladorackle profile image
Orackle

Such an excellent guide. Very concise and straight to the point. Thank you