基于此article,我为UICollectionView
创建了可重用的数据源,如下所示:-
final class CollectionViewDataSource<Model>: NSObject, UICollectionViewDataSource {
typealias CellConfigurator = (Model, UICollectionViewCell) -> Void
var models: [Model] = []
private let reuseIdentifier: String
private let cellConfigurator: CellConfigurator
init(reuseIdentifier: String, cellConfigurator: @escaping CellConfigurator) {
self.reuseIdentifier = reuseIdentifier
self.cellConfigurator = cellConfigurator
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return models.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let model = models[indexPath.item]
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath)
cellConfigurator(model, cell)
return cell
}
}
然后我扩展了此类,因此我可以根据模型的类型提供“特定于单元的设置”
extension CollectionViewDataSource where Model == HomeFeedItem {
static func make(reuseIdentifier: String = "FEED_ARTICLE_CELL") -> CollectionViewDataSource {
return CollectionViewDataSource(reuseIdentifier: reuseIdentifier, cellConfigurator: { item, cell in
(cell as? FeedArticleCell)?.render(with: item)
})
}
}
extension CollectionViewDataSource where Model == HomeFeedAlertItem {
static func make(reuseIdentifier: String = "FEED_ALERT_CELL") -> CollectionViewDataSource {
return CollectionViewDataSource(reuseIdentifier: reuseIdentifier, cellConfigurator: { item, cell in
(cell as? FeedAlertCell)?.render(with: item)
})
}
}
这很完美,但是,每个单元格都有不同的设计,但实际上接受的属性非常相似(其他单元格也一样)-因此,我正在考虑创建简单的FeedItemModel
并映射这些属性在渲染我的提要之前。这样可以确保在我渲染提要项的任何地方,我始终都处理相同的属性。
考虑到这一点,我试图创建类似:-
的东西extension CollectionViewDataSource where Model == FeedItemModel {
static func make(reuseIdentifier: String = "FEED_ARTICLE_CELL") -> CollectionViewDataSource {
return CollectionViewDataSource(reuseIdentifier: reuseIdentifier, cellConfigurator: { item, cell in
switch item.type {
case .news: (cell as? FeedArticleCell)?.render(with: item)
case .alert: (cell as? FeedAlertCell)?.render(with: item)
}
})
}
}
然而,由于reuseIdentifier
为item.type
,.alert
字段不再正确,因此该值下降。
如何重构此模式,以使我可以在同一模型中使用不同的像元类型?还是我应该放弃这种方法而对每种单元格类型使用不同的模型,而不管输入属性是否相同?]
如何为单元添加第二个通用类型