Question: How to write a default implementation of UITableViewDataSource
by extending it?
Swift supports default implementations in protocol extensions, and UITableViewDataSource
is a protocol. So why doesn't the example below work?
I tried the example below, but the table stays blank. To be sure, I added breakpoints to the default implementations, and they aren't reached. I put print
methods inside but they print nothing.
This extension would make usage of basic table views almost code-less, as they'd only need a collection of entities that conform to TableItem
.
This question with similar title is unrelated.
Full example:
import UIKit
/// Conform to this protocol to be immediatelly usable in table views.
protocol TableItem {
var textLabel: String? { get }
var detailTextLabel: String? { get }
}
protocol BasicTableDataSource {
associatedtype TableItemType: TableItem
var tableItems: [TableItemType]? { get set }
/// The table view will dequeue a cell with this identifier.
/// Leave empty to use `cellStyle`.
var cellIdentifier: String? { get set }
/// If `cellIdentifier` is empty, the table view will use this cell style.
/// Leave empty to use `UITableViewCellStyle.default`.
var cellStyle: UITableViewCellStyle? { get set }
}
extension UITableViewDataSource where Self: BasicTableDataSource {
func tableView(
_ tableView: UITableView,
numberOfRowsInSection section: Int) -> Int {
return tableItems?.count ?? 0
}
func tableView(
_ tableView: UITableView,
cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = cellIdentifier == nil
? UITableViewCell(
style: cellStyle ?? .default,
reuseIdentifier: nil)
: tableView.dequeueReusableCell(
withIdentifier: cellIdentifier!,
for: indexPath)
let tableItem = tableItems?[indexPath.row]
cell.textLabel?.text = tableItem?.textLabel
cell.detailTextLabel?.text = tableItem?.detailTextLabel
return cell
}
}
class ProductsTableViewController: UITableViewController, BasicTableDataSource {
var cellIdentifier: String?
var cellStyle: UITableViewCellStyle? = .subtitle
/// Product conforms to TableItem
var tableItems: [Product]? = Sample.someProducts()
}