A subclass of UITableView
with expandable and collapsible sections
CocoaPods is a dependency manager for Cocoa projects. You can install it with the following command:
$ sudo gem install cocoapods
CocoaPods 1.14.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, '13.0'
use_frameworks!
target '<Your Target Name>' do
pod 'LUExpandableTableView'
end
Then, run the following command:
$ pod install
To integrate using Apple's Swift Package Manager, add the following as a dependency to your Package.swift
:
.package(url: "https://github.com/LaurentiuUngur/LUExpandableTableView", from: Version(6, 0, 0))
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 ofUITableViewCell
. 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 ofLUExpandableTableViewSectionHeader
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
andLUExpandableTableViewDelegate
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)")
}
}
- Xcode 15.0+
- Swift 5.9+
- iOS 13.0+
- LUExpandableTableView is available under the MIT license.