Swiftpack.co - Package - LaurentiuUngur/LUExpandableTableView


A subclass of UITableView with expandable and collapsible sections

Build Status Swift 5 Carthage compatible Swift Package Manager compatible Pod Version Pod Platform Pod License




CocoaPods is a dependency manager for Cocoa projects. You can install it with the following command:

$ sudo gem install cocoapods

CocoaPods 1.7.0+ is required.

To integrate LUExpandableTableView into your Xcode project using CocoaPods, specify it in your Podfile:

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '9.0'

target '<Your Target Name>' do
    pod 'LUExpandableTableView'

Then, run the following command:

$ pod install


You can use Carthage to install LUExpandableTableView by adding it to your Cartfile:

github "LaurentiuUngur/LUExpandableTableView" ~> 5.0

Then run carthage update.

If this is your first time using Carthage in the project, you'll need to go through some additional steps as explained over at Carthage.

Swift Package Manager

To integrate using Apple's Swift Package Manager, add the following as a dependency to your Package.swift:

.Package(url: "https://githubLaurentiuUngur/LUExpandableTableView", majorVersion: 5)

Here's an example of PackageDescription:

import PackageDescription

let package = Package(name: "MyApp",
    dependencies: [
        .Package(url: "https://github.com/LaurentiuUngur/LUExpandableTableView", majorVersion: 5)


If you prefer not to use either of the before mentioned dependency managers, you can integrate LUExpandableTableView into your project manually.


  • Import LUExpandableTableView into your project.
import LUExpandableTableView
  • Register a cell for an instance of LUExpandableTableView. Registered class must be a subclass of UITableViewCell. This step is not be necessary if you use storyboard.
expandableTableView.register(MyTableViewCell.self, forCellReuseIdentifier: cellReuseIdentifier)
  • Register a header for an instance of LUExpandableTableView. Registered class must be a subclass of LUExpandableTableViewSectionHeader Keep in mind that you cannot use storyboard in order to do this.
expandableTableView.register(UINib(nibName: "MyExpandableTableViewSectionHeader", bundle: Bundle.main), forHeaderFooterViewReuseIdentifier: sectionHeaderReuseIdentifier)
  • Set as data source and delegate.
expandableTableView.expandableTableViewDataSource = self
expandableTableView.expandableTableViewDelegate = self
  • Implement LUExpandableTableViewDataSource and LUExpandableTableViewDelegate protocols.
// MARK: - LUExpandableTableViewDataSource

extension ViewController: LUExpandableTableViewDataSource {
   func numberOfSections(in expandableTableView: LUExpandableTableView) -> Int {
       return 42
   func expandableTableView(_ expandableTableView: LUExpandableTableView, numberOfRowsInSection section: Int) -> Int {
       return 3
   func expandableTableView(_ expandableTableView: LUExpandableTableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
       guard let cell = expandableTableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as? MyTableViewCell else {
           assertionFailure("Cell shouldn't be nil")
           return UITableViewCell()
       cell.label.text = "Cell at row \(indexPath.row) section \(indexPath.section)"
       return cell
   func expandableTableView(_ expandableTableView: LUExpandableTableView, sectionHeaderOfSection section: Int) -> LUExpandableTableViewSectionHeader {
       guard let sectionHeader = expandableTableView.dequeueReusableHeaderFooterView(withIdentifier: sectionHeaderReuseIdentifier) as? MyExpandableTableViewSectionHeader else {
           assertionFailure("Section header shouldn't be nil")
           return LUExpandableTableViewSectionHeader()
       sectionHeader.label.text = "Section \(section)"
       return sectionHeader

// MARK: - LUExpandableTableViewDelegate

extension ViewController: LUExpandableTableViewDelegate {
   func expandableTableView(_ expandableTableView: LUExpandableTableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
       /// Returning `UITableViewAutomaticDimension` value on iOS 9 will cause reloading all cells due to an iOS 9 bug with automatic dimensions
       return 50
   func expandableTableView(_ expandableTableView: LUExpandableTableView, heightForHeaderInSection section: Int) -> CGFloat {
       /// Returning `UITableViewAutomaticDimension` value on iOS 9 will cause reloading all cells due to an iOS 9 bug with automatic dimensions
       return 69
   // MARK: - Optional
   func expandableTableView(_ expandableTableView: LUExpandableTableView, didSelectRowAt indexPath: IndexPath) {
       print("Did select cell at section \(indexPath.section) row \(indexPath.row)")
   func expandableTableView(_ expandableTableView: LUExpandableTableView, didSelectSectionHeader sectionHeader: LUExpandableTableViewSectionHeader, atSection section: Int) {
       print("Did select cection header at section \(section)")
   func expandableTableView(_ expandableTableView: LUExpandableTableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
       print("Will display cell at section \(indexPath.section) row \(indexPath.row)")
   func expandableTableView(_ expandableTableView: LUExpandableTableView, willDisplaySectionHeader sectionHeader: LUExpandableTableViewSectionHeader, forSection section: Int) {
       print("Will display section header for section \(section)")

For more usage details please see example app


  • Returning UITableViewAutomaticDimension value on iOS 9 will cause reloading all cells due to an iOS 9 bug with automatic dimensions. On iOS 10 it works fine.


  • Xcode 10.2+
  • Swift 5.0+
  • iOS 9.0+



  • LUExpandableTableView is available under the MIT license.


Stars: 113
Help us keep the lights on


Used By



5.0.0 - Apr 16, 2019

  • Swift 5 and Xcode 10.2 support

4.1.0 - Mar 12, 2019

  • Add expandableTableView(:, viewForFooterInSection:) delegate function
  • Add expandableTableView(:, heightForHeaderInSection:) delegate function

4.0.0 - Sep 20, 2018

  • Xcode 10 and Swift 4.2 support

3.0.0 - Sep 27, 2017

  • Swift 4 and Xcode 9 support
  • Add Carthage support

2.1.0 - Apr 19, 2017

  • Add ability to expand or collapse sections programatically