在UICollectionView中没有开关的Deque可重用单元

时间:2017-01-26 11:34:23

标签: ios swift

我注意到在向UICollectionView添加越来越多的单元格类型时,维护代码更加困难。因此,根据我们在添加新功能时不应更改代码的原则,我们应该添加新代码。

让我们从例子开始。

我们有这样的数据模型:

protocol Animal {}

class Dog: Animal {}

class Duck: Animal {}

我们有两个合适的单元格 - DogCellDuckCell

根据许多教程,我们可以在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代码也将受到赞赏。

1 个答案:

答案 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)
}