Вы не можете использовать общие протоколы иначе, чем ограничения типа.Без определения универсального типа компилятор не может сравнивать соответствие типов.Если я вас правильно понял, то вам нужно определить универсальный CellConfigurator
класс.Одно из возможных решений ниже:
1.Абстракции ячеек и конфигуратора
protocol ConfigurableCell {
associatedtype DataType
func configure(viewModel: DataType?)
}
protocol CollectionViewCellConfigurator {
static var reuseId: String { get }
func configure(cell: UICollectionViewCell)
var item: UniqueIdentifiable? { get }
}
final class CellConfigurator<CellType: ConfigurableCell, DataType>: CollectionViewCellConfigurator where CellType.DataType == DataType, CellType: UICollectionViewCell {
/// Cell Reuse identifier
static var reuseId: String { return CellType.reuseId }
/// Configures cell and populates it with `viewModel`
///
/// - Parameter cell: Cell to configure
func configure(cell: UICollectionViewCell) {
(cell as! CellType).configure(viewModel: item as? DataType)
}
/// Initializer
///
/// - Parameter item: Data item (usually ViewModel of the cell)
init(item: DataType?) {
self.item = item
}
}
2.Использование
Ваш источник данных теперь будет работать с CellConfigurators
в виде CellConfigurator<CellType /*UI(CollectionView/TableView)Cell subclass*/, CellData /*Data you need to populate to the cell*/>(item: cellData)
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let configItem = yourDataSource.rows[indexPath.row]
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: type(of: configItem).reuseId, for: indexPath)
configItem.configure(cell: cell)
return cell
}
Надеюсь, это поможет.Удачи