Skip to content

Instantly share code, notes, and snippets.

@rothmichaels
Last active October 4, 2022 11:20
Show Gist options
  • Select an option

  • Save rothmichaels/e6ae55c89ee58d7e5254 to your computer and use it in GitHub Desktop.

Select an option

Save rothmichaels/e6ae55c89ee58d7e5254 to your computer and use it in GitHub Desktop.
Enumerated UITableViewCell identifier example
import UIKit
/// Protocol to be implemented by table view cell identifier enums
protocol TableViewCellIdentifier {
var identifierString: String { get }
}
/// Extension to provide default impementation for RawRepresentable String enums
extension TableViewCellIdentifier where Self: RawRepresentable, Self.RawValue == String {
var identifierString: String {
return self.rawValue
}
}
/// Table View section type
enum SectionType<T: TableViewCellIdentifier> {
case Static([T])
case Dynamic(TableViewDelegateDataSource)
}
/// Protocol for objects implementing both UITableViewDataSource and UITableViewDelegate
protocol TableViewDelegateDataSource: UITableViewDelegate, UITableViewDataSource { }
// Main tableview delegate/dataSource object
class DataSource: NSObject, TableViewDelegateDataSource {
enum CellIdentifier: String, TableViewCellIdentifier {
case Header
case Main
case FirstDetail
case SecondDetail
}
typealias Section = SectionType<CellIdentifier>
let sections: [DataSource.Section] = [
.Static([.Header]),
.Dynamic(OtherDataSource()),
.Static([.Main,.FirstDetail,.SecondDetail])
]
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return sections.count
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
assert(section < sections.count)
switch sections[section] {
case .Static(let rows):
return rows.count
case .Dynamic(let dataSource):
return dataSource.tableView(tableView, numberOfRowsInSection: section)
}
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
assert(indexPath.section < sections.count)
switch sections[indexPath.section] {
case .Static(let rows):
let row = rows[indexPath.row]
let cell = tableView.dequeueReusableCellWithIdentifier(row.rawValue, forIndexPath: indexPath)
switch row {
case .Header:
cell.textLabel?.text = "Hello, world!"
case .Main:
cell.textLabel?.text = "Lorem ipsum dolor sit amet."
case .FirstDetail:
cell.textLabel?.text = "Aliquam ut orci turpis. Maecenas mauris ligul"
cell.detailTextLabel?.text = "Integer sed mi id risus fermentum dignissim"
case .SecondDetail:
cell.textLabel?.text = "Lorem ipsum dolor sit amet."
cell.detailTextLabel?.text = "Cras dui lorem"
}
return cell
case .Dynamic(let dataSource):
return dataSource.tableView(tableView, cellForRowAtIndexPath: indexPath)
}
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
switch sections[indexPath.section] {
case .Static(_):
return
case .Dynamic(let delegate):
delegate.tableView?(tableView, didSelectRowAtIndexPath: indexPath)
}
}
}
/// Child data source to be used with `DataSource` or in its own view controller
class OtherDataSource: NSObject, TableViewDelegateDataSource {
let details = ["thing one", "thing two"]
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return details.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(DataSource.CellIdentifier.SecondDetail.rawValue, forIndexPath: indexPath)
cell.textLabel?.text = details[indexPath.row]
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
cellSelectionAction(indexPath.row)
}
func cellSelectionAction(index: Int) {
// do something
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment