Stuart Breckenridge

Encapsulating Table View Row Functions in a Struct

During a recent refactor of a table view data source, I created a struct for table view row data that would encapsulate both UI data and any necessary function to perform when the row is selected. It looks like this:

struct TableViewRowData {
    var title: String
    var performingFunction: (() -> Void)?
}

Adding a few TableViewRowData entries to an array:

let dataSource: [TableViewRowData] = [
    TableViewRowData(title: "Row 1", performingFunction: {
		print("Row 1")
	}),
    TableViewRowData(title: "Row 2", performingFunction: {
		print("Row 2")
	})
]

Then, in the UITableViewDataSource:

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return dataSource.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    guard let cell = tableView.dequeueReusableCell(withIdentifier: "rowCell", for: indexPath) as? TableViewCell else {
        return UITableViewCell()
    }

    cell.titleLabel.text = dataSource[indexPath.row].title

    return cell
}

And in the UITableViewDelegate:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    dataSource[indexPath.row].performingFunction?()
    tableView.deselectRow(at: indexPath, animated: true)
    tableView.reloadData()
}

This approach keeps the UITableViewDataSource and UITableViewDelegate a bit tidier.


— Supported by —