Swift DRY collectionView(_ cellForItemAt) 调用

Posted

技术标签:

【中文标题】Swift DRY collectionView(_ cellForItemAt) 调用【英文标题】:Swift DRY collectionView(_ cellForItemAt) call 【发布时间】:2018-02-27 18:58:00 【问题描述】:

当我有不同类型的单元格时,我发现自己经常做这种重复的代码。有没有办法把它弄干?或者它是否尽可能好。

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
        switch cells[indexPath.item].type 
        case .aCell:
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: ACellID, for: indexPath) as! ACell
            cell.data = somedata
            return cell
        case .bCell:
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: BCellID, for: indexPath) as! BCell
            cell.data = somedata
            return cell
        case .cCell:
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CCellID, for: indexPath) as! CCell
            cell.data = somedata
            return cell 
        
    

我正在考虑让所有单元格采用 protocol 并将它们放入一个数组中

【问题讨论】:

我看到相同的模块 var 它们之间的主要区别是什么?? 不管怎样,我在很多不同的代码库中都有这种模式,我个人认为任何进一步删除重复的尝试都违反了其他一些编程原则,或者只是没有改进解决方案。 【参考方案1】:

据我了解,您可以使用所有单元格都可以遵守的协议,并扩展您的单元格类型枚举以返回单元格 ID,这样您就不需要每次都切换到出列。

enum CellType 
    case aCell, bCell, cCell

    var id: String 
        switch self 
        case .aCell: return "aCellId"
        case .bCell: return "bCellId"
        case .cCell: return "cCellId"
        
    


protocol CellData 

    // Remove since you probably have your modlue type.
    typealias Module = String

    var type: CellType  get 
    var modlues: [Module]  get  // Module type


protocol CommonCellProperty: AnyObject 
    var data: CellData!  get 


typealias CommonCell = CommonCellProperty & UICollectionViewCell

class MasterCell: UICollectionViewCell, CommonCellProperty 
    var data: CellData! // set data

class HolderCell: UICollectionViewCell, CommonCellProperty 
    var data: CellData! // set data

//...

class ViewController: UIViewController, UICollectionViewDataSource 

    var cells: [CellData] = []

    override func viewDidLoad() 
        super.viewDidLoad()

    

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 

        let cellData: CellData = cells[indexPath.section]
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellData.type.id, for: indexPath) as! CommonCell

        //cell.data = somedata

        return cell
    

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
        return cells.count
    


【讨论】:

【参考方案2】:

是的,如果这真的是您的代码模式并且唯一不同的是标识符,我建议创建一个字典,其中键是单元格类型,值是标识符:

//Create a dictionary to map from cell type to identifier
let cellIDs = [
  .aCell: ACellID,
  .bCell: BCellID,
  .cCell: CCellID
]

//Define a common class for the different cell types
class MyCell: UICollectionViewViewCell 
  var data: Data



override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 

  let cell: MyCell
  let cellType = cells[indexPath.item].type
  let cellIdentifier = cellIDs[cellType]
  cell = collectionView.dequeueReusableCell(
    withReuseIdentifier: 
    cellIdentifier, 
    for: indexPath) as! MyCell
  cell.data = someData
  return cell

或者,将另一个字段 identifier 添加到包含每个单元格类型的数组 cells 中,然后像当前处理单元格类型一样从该数组中获取单元格的重用标识符。

【讨论】:

在 OP 中,单元格被实例化为不同的 UITableViewCell 子类。此解决方案不适用于此。

以上是关于Swift DRY collectionView(_ cellForItemAt) 调用的主要内容,如果未能解决你的问题,请参考以下文章

Swift:按下collectionView项目时推送新视图

swift 优化Swift CollectionView和TableView

swift中collectionView的简单用法

Swift 3 - CollectionView 选择不可见

CollectionView 在 StackView (Swift) 中消失

在 iOS Swift 中,在 Swift 4 中的 TableView 中为 CollectionView 集成不同的数组