我注意到在向UICollectionView添加越来越多的单元格类型时,维护代码更加困难。因此,根据我们在添加新功能时不应更改代码的原则,我们应该添加新代码。
让我们从例子开始。
我们有这样的数据模型:
protocol Animal {}
class Dog: Animal {}
class Duck: Animal {}
我们有两个合适的单元格 - DogCell
和DuckCell
。
根据许多教程,我们可以在UICollectionViewDataSource
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let animal = self.animals[indexPath.row]
if let dog = animal as? Dog {
return collectionView.dequeueReusableCell(withReuseIdentifier: "DogCell", for: indexPath)
} else if let duck = animal as? Duck {
return collectionView.dequeueReusableCell(withReuseIdentifier: "DuckCell", for: indexPath)
}
return UICollectionViewCell()
}
现在我们要根据CatCell
模型添加另一个Cat
的单元格。
为更干净的代码添加另一个else if
是不好的做法,那么如何在iOS中执行此操作?那有什么好的设计模式吗? Objective-C代码也将受到赞赏。
答案 0 :(得分:1)
添加一个新协议,该协议具有针对单元标识符的计算字符串变量。
protocol AnimalCell {
var cellReuseIdentifier: String { get }
}
让Animal协议符合procol。
extension Animal: AnimalCell { }
将cellReuseIdentifier添加到类
extension Dog: Animal {
var cellReuseIdentifier: String {
return "DogCell"
}
}
extension Duck: Animal {
var cellReuseIdentifier: String {
return "DuckCell"
}
}
然后,您只需将cellReuseIdentifier
设置为标识符。
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let animal = self.animals[indexPath.row]
return collectionView.dequeueReusableCell(withReuseIdentifier: animal.cellReuseIdentifier, for: indexPath)
}