Consider an example:
protocol CellConfigurator {
var cellClass: UICollectionViewCell.Type {get}
func configure(cell: UICollectionViewCell)
}
class AppleCell: UICollectionViewCell {
let title = UILabel()
}
class AppleCellConfigurator: CellConfigurator {
let cellClass: UICollectionViewCell.Type = AppleCell.self
func configure(cell: UICollectionViewCell) {
guard let cell = cell as? AppleCell else {return}
cell.title.text = "AAPL"
}
}
I can use the aforementioned pattern to encapsulate the actual type of the UICollectionViewCell
, use it as follows (pseudocode):
func cellAt(indexPath: IndexPath) -> UICollectionViewCell {
let configurator = configurators[indexPath]
let cell = collectionView.dequeueReusableCell(identifier: String(describing: configurator.cellClass))
configurator.configure(cell)
return cell
}
I'm looking forward to getting rid of the necessity to type-cast the cell in every conforming to CellConfigurator
, for example, using protocols with associated types:
protocol CellConfigurator {
associatedtype Cell
func configure(cell: Cell)
}
class AppleCell: UICollectionViewCell {
let title = UILabel()
}
class AppleCellConfigurator: CellConfigurator {
typealias Cell = AppleCell
func configure(cell: Cell) {
cell.title.text = "AAPL"
}
}
However, I can't hold them together in an array due to an error: "Protocol 'SomeProtocol' can only be used as a generic constraint because it has Self or associated type requirements".
Is there any way to achieve the two goals:
- Having a function with
UICollectionViewCell
parameter type for anyCellConfigurator
? - Having a concrete type inside the function of a particular configurator
CellConfigurator
and thenAppleCellConfigurator
will inherit from that class. – Kamran