You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在CellForRowAt中高效出队自定义TableViewCell,避免违反开闭原则?

优化UITableView多Cell实现方案(无大量if-else+符合开闭原则)

针对你当前用大量if-else判断Cell类型的问题,推荐用CellViewModel协议+统一数据数组的方式实现,完全符合开闭原则,新增Cell时无需修改ViewController核心逻辑。

步骤1:定义CellViewModel协议

先定义一个协议,让所有Cell对应的数据模型都遵循这个协议,协议包含Cell的标识和配置Cell的方法:

protocol TableCellViewModel {
    var cellIdentifier: String { get }
    func configure(cell: UITableViewCell)
}

步骤2:为每个自定义Cell实现对应的CellViewModel

把原来分散在cellForRowAt里的配置逻辑(包括特殊的UI调整,比如SecondCell的高度设置)转移到对应的CellViewModel中:

FirstCell对应的ViewModel

struct FirstCellViewModel: TableCellViewModel {
    let data: FirstCellData // 你原来的FirstCell数据结构体
    
    var cellIdentifier: String {
        return "firstCell"
    }
    
    func configure(cell: UITableViewCell) {
        guard let firstCell = cell as? FirstCell else { return }
        firstCell.configure(data: data)
    }
}

SecondCell对应的ViewModel

struct SecondCellViewModel: TableCellViewModel {
    let data: SecondCellData // 你原来的SecondCell数据结构体
    
    var cellIdentifier: String {
        return "secondCell"
    }
    
    func configure(cell: UITableViewCell) {
        guard let secondCell = cell as? SecondCell else { return }
        secondCell.configure(data: data)
        // 把原来在ViewController里的高度调整逻辑移到这里
        secondCell.productSpecificationsTableViewHeight.constant = secondCell.productSpecificationsTableView.contentSize.height
    }
}

步骤3:修改主ViewModel的数据源结构

把原来单个的firstCellData、secondCellData改成一个TableCellViewModel类型的数组,按Cell的显示顺序排列:

class MainViewModel {
    var cellViewModels: [TableCellViewModel] = []
    
    // 初始化或数据加载时,按顺序添加各个Cell的ViewModel
    func loadData() {
        // 示例:添加FirstCell的ViewModel
        let firstData = FirstCellData(/* 初始化数据 */)
        cellViewModels.append(FirstCellViewModel(data: firstData))
        
        // 添加SecondCell的ViewModel
        let secondData = SecondCellData(/* 初始化数据 */)
        cellViewModels.append(SecondCellViewModel(data: secondData))
        
        // 后续新增Cell,直接在这里添加对应的ViewModel即可
    }
}

步骤4:简化ViewController的cellForRowAt方法

现在不需要任何if-else判断,直接从ViewModel的数组中取对应的数据模型,完成Cell的出队和配置:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cellViewModel = viewModel.cellViewModels[indexPath.row]
    let cell = tableView.dequeueReusableCell(withIdentifier: cellViewModel.cellIdentifier, for: indexPath)
    cellViewModel.configure(cell: cell)
    return cell
}

新增Cell的流程(完全符合开闭原则)

当需要新增自定义Cell时,只需要做3件事:

  1. 创建新的Cell类(比如ThirdCell),实现自己的configure(data:)方法
  2. 创建对应的ThirdCellViewModel,遵循TableCellViewModel协议,实现标识和配置逻辑
  3. 在主ViewModel的loadData()方法中,把ThirdCellViewModel添加到cellViewModels数组里

整个过程不需要修改ViewController的任何代码,完全符合对扩展开放,对修改关闭的开闭原则。

内容的提问来源于stack exchange,提问作者Rohit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 13:50:45