如何使用外部数据源转换单元格类型
How to Cast Cell Type with External DataSource
我有以下用于各种 tableView 的外部数据源。
我想让它动态化,并能够将 CellConfigurator
中的 UITableViewCell
投射到各种自定义单元格。我为下面的每个模型做了一个扩展。但我需要能够转换为扩展中的不同单元格类型。
import UIKit
class ProductSearchDataSource<Model>: NSObject, UITableViewDataSource {
typealias CellConfigurator = (Model, UITableViewCell) -> Void
var models: [Model]
private let reuseIdentifier: String
private let cellConfigurator: CellConfigurator
init(models: [Model], reuseIdentifier: String, cellConfigurator: @escaping CellConfigurator) {
self.models = models
self.reuseIdentifier = reuseIdentifier
self.cellConfigurator = cellConfigurator
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return models.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let model = models[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier, for: indexPath)
cellConfigurator(model, cell)
return cell
}
}
extension ProductSearchDataSource where Model == ProductSearchHistory {
static func make(for productSearch: [ProductSearchHistory], reuseIdentifier: String = "productSearchTableViewCell") -> ProductSearchDataSource {
return ProductSearchDataSource(models: productSearch, reuseIdentifier: reuseIdentifier) { (productSearch, productSearchTableViewCell) in
productSearchTableViewCell.textLabel?.text = productSearch.searchHistory
}
}
}
您需要为单元格引入额外的占位符类型:
class ProductSearchDataSource<Model, Cell: UITableViewCell>: NSObject, UITableViewDataSource {
typealias CellConfigurator = (Model, Cell) -> Void
...
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let model = models[indexPath.row]
// Note: You may want to handle the downcast better...
let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier, for: indexPath) as! Cell
cellConfigurator(model, cell)
return cell
}
}
extension ProductSearchDataSource where Model == ProductSearchHistory, Cell == ProductSearchCell {
static func make(for productSearch: [ProductSearchHistory], reuseIdentifier: String = "productSearchTableViewCell") -> ProductSearchDataSource {
return ProductSearchDataSource(models: productSearch, reuseIdentifier: reuseIdentifier) { (productSearch, productSearchTableViewCell) in
// `productSearchTableViewCell` will now have a type of `ProductSearchCell `.
productSearchTableViewCell.textLabel?.text = productSearch.searchHistory
}
}
}
我有以下用于各种 tableView 的外部数据源。
我想让它动态化,并能够将 CellConfigurator
中的 UITableViewCell
投射到各种自定义单元格。我为下面的每个模型做了一个扩展。但我需要能够转换为扩展中的不同单元格类型。
import UIKit
class ProductSearchDataSource<Model>: NSObject, UITableViewDataSource {
typealias CellConfigurator = (Model, UITableViewCell) -> Void
var models: [Model]
private let reuseIdentifier: String
private let cellConfigurator: CellConfigurator
init(models: [Model], reuseIdentifier: String, cellConfigurator: @escaping CellConfigurator) {
self.models = models
self.reuseIdentifier = reuseIdentifier
self.cellConfigurator = cellConfigurator
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return models.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let model = models[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier, for: indexPath)
cellConfigurator(model, cell)
return cell
}
}
extension ProductSearchDataSource where Model == ProductSearchHistory {
static func make(for productSearch: [ProductSearchHistory], reuseIdentifier: String = "productSearchTableViewCell") -> ProductSearchDataSource {
return ProductSearchDataSource(models: productSearch, reuseIdentifier: reuseIdentifier) { (productSearch, productSearchTableViewCell) in
productSearchTableViewCell.textLabel?.text = productSearch.searchHistory
}
}
}
您需要为单元格引入额外的占位符类型:
class ProductSearchDataSource<Model, Cell: UITableViewCell>: NSObject, UITableViewDataSource {
typealias CellConfigurator = (Model, Cell) -> Void
...
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let model = models[indexPath.row]
// Note: You may want to handle the downcast better...
let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier, for: indexPath) as! Cell
cellConfigurator(model, cell)
return cell
}
}
extension ProductSearchDataSource where Model == ProductSearchHistory, Cell == ProductSearchCell {
static func make(for productSearch: [ProductSearchHistory], reuseIdentifier: String = "productSearchTableViewCell") -> ProductSearchDataSource {
return ProductSearchDataSource(models: productSearch, reuseIdentifier: reuseIdentifier) { (productSearch, productSearchTableViewCell) in
// `productSearchTableViewCell` will now have a type of `ProductSearchCell `.
productSearchTableViewCell.textLabel?.text = productSearch.searchHistory
}
}
}