制作一个通用的 TableView 数据源 class
Make a generic TableView DataSource class
我想创建一个通用的 TableView 数据源 class,它包含一个 ConfigureModel
:
的数组
protocol ConfigureModel {
associatedtype ModelType
var name: String { get set }
var modelDescription: String { get }
}
我也希望 TableView 单元格是通用的:
class ConfigureCell<ConfigureType>: UITableViewCell, Configure {
func configure<Model: ConfigureModel>(with value: Model) where ConfigureType == Model.ModelType {
let description = value.modelDescription
print("ConfigureCell description: \(description)")
}
}
所以我让 ConfigureCell
采用了通用的 Configure
协议:
protocol Configure {
associatedtype ConfigureType
func configure<Model: ConfigureModel>(with value: Model) where Model.ModelType == ConfigureType
}
现在我可以让模型采用 ConfigureModel
协议,以便能够在 ConfigureCell
class:
中使用
struct Tag {
....
}
extension Tag: ConfigureModel {
typealias ModelType = Tag
}
这很好用。现在使 ObjectDataSource
通用:
class ObjectDataSource<T: ConfigureModel>: NSObject, UITableViewDataSource, UITableViewDelegate {
var values: [T] = []
....
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let item = self.values[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "TagCell", for: indexPath) as! ConfigureCell<T>
cell.configure(with: item)
这里我有一个问题,我已经尝试了很多小时来解决。最后一个 cell.configure(with: item
语句 Xcode 显示错误:Instance method 'configure(with:)' requires the types 'T' and 'T.T' be equivalent
我知道我必须在 class 中创建一个通用的 where 子句,但我很难找到它应该是什么。
class ObjectDataSource<T: ConfigureModel>: NSObject, UITableViewDataSource, UITableViewDelegate
where T == ???? {
我制作了一个可以运行的 Xcode 游乐场,但注释掉的部分不起作用。你可以在这里得到它:GenericDataSource Xcode PlayGround
I also want the TableView cell to be generic
你根本不需要那个。您已经将 configure(with:)
方法定义为通用方法。无需将 class 本身设为通用。
鉴于上述陈述,如果您不介意的话,下面是您的简单实现:
class ConfigureCell: UITableViewCell {
func configure<Model: ConfigureModel>(with value: Model) {
let description = value.modelDescription()
print("ConfigureCell description: \(description)")
}
}
class ObjectDataSource<T: ConfigureModel>: NSObject, UITableViewDataSource {
var values: [T] = []
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return values.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let item = self.values[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "TagCell", for: indexPath) as! ConfigureCell
cell.configure(with: item)
return cell
}
}
我想创建一个通用的 TableView 数据源 class,它包含一个 ConfigureModel
:
protocol ConfigureModel {
associatedtype ModelType
var name: String { get set }
var modelDescription: String { get }
}
我也希望 TableView 单元格是通用的:
class ConfigureCell<ConfigureType>: UITableViewCell, Configure {
func configure<Model: ConfigureModel>(with value: Model) where ConfigureType == Model.ModelType {
let description = value.modelDescription
print("ConfigureCell description: \(description)")
}
}
所以我让 ConfigureCell
采用了通用的 Configure
协议:
protocol Configure {
associatedtype ConfigureType
func configure<Model: ConfigureModel>(with value: Model) where Model.ModelType == ConfigureType
}
现在我可以让模型采用 ConfigureModel
协议,以便能够在 ConfigureCell
class:
struct Tag {
....
}
extension Tag: ConfigureModel {
typealias ModelType = Tag
}
这很好用。现在使 ObjectDataSource
通用:
class ObjectDataSource<T: ConfigureModel>: NSObject, UITableViewDataSource, UITableViewDelegate {
var values: [T] = []
....
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let item = self.values[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "TagCell", for: indexPath) as! ConfigureCell<T>
cell.configure(with: item)
这里我有一个问题,我已经尝试了很多小时来解决。最后一个 cell.configure(with: item
语句 Xcode 显示错误:Instance method 'configure(with:)' requires the types 'T' and 'T.T' be equivalent
我知道我必须在 class 中创建一个通用的 where 子句,但我很难找到它应该是什么。
class ObjectDataSource<T: ConfigureModel>: NSObject, UITableViewDataSource, UITableViewDelegate
where T == ???? {
我制作了一个可以运行的 Xcode 游乐场,但注释掉的部分不起作用。你可以在这里得到它:GenericDataSource Xcode PlayGround
I also want the TableView cell to be generic
你根本不需要那个。您已经将 configure(with:)
方法定义为通用方法。无需将 class 本身设为通用。
鉴于上述陈述,如果您不介意的话,下面是您的简单实现:
class ConfigureCell: UITableViewCell {
func configure<Model: ConfigureModel>(with value: Model) {
let description = value.modelDescription()
print("ConfigureCell description: \(description)")
}
}
class ObjectDataSource<T: ConfigureModel>: NSObject, UITableViewDataSource {
var values: [T] = []
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return values.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let item = self.values[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "TagCell", for: indexPath) as! ConfigureCell
cell.configure(with: item)
return cell
}
}