Создайте универсальный класс TableView DataSource
Я хочу сделать общий класс TableView DataSource, который содержит массив 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
учебный класс:
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
Я понимаю, что я должен сделать общее предложение where в классе, но у меня возникают проблемы с выяснением, что это должно быть.
class ObjectDataSource<T: ConfigureModel>: NSObject, UITableViewDataSource, UITableViewDelegate
where T == ???? {
Я создал игровую площадку Xcode, которая работает, но закомментированные части не работают. Вы можете получить его здесь: GenericDataSource Xcode PlayGround
1 ответ
Я также хочу, чтобы ячейка TableView была универсальной
Тебе это просто не нужно. Вы уже определили configure(with:)
метод, чтобы быть универсальным. Не нужно делать сам класс универсальным.
Учитывая приведенное выше утверждение, если вы согласны с этим, ваша реализация будет такой простой, как:
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
}
}