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

iOS Swift中创建符合规范的MVVM ViewModel用于UITableView数据展示

适配UITableView的规范ViewModel实现方案

原有实现问题

  • 数据结构拆分不合理:header列表和行数据完全分离,没有对应绑定关系,无法通过section索引拿到对应分组的行数据
  • 代理方法逻辑存在矛盾:原有代码尝试从String类型的header元素中取listItem属性,语法完全不成立

修正后的完整代码

ViewModel层代码

// 分组类型枚举
enum HeaderType {
    case information
    case documents
}

// 行数据模型
struct ListData {
    var title: String
    var type: HeaderType
}

// 分组数据模型:绑定每个section的header标题和对应行数据
struct TableSectionModel {
    var headerTitle: String
    var rowList: [ListData]
}

// 主ViewModel
struct MyViewModel {
    // 所有分组数据,直接对应tableView的section结构
    var sectionList: [TableSectionModel]
    
    // 默认构造器,直接生成示例数据
    init() {
        // 第一个分组:信息类
        let infoSection = TableSectionModel(
            headerTitle: "信息查询",
            rowList: [ListData(title: "查看详细信息", type: .information)]
        )
        // 第二个分组:文件类
        let docSection = TableSectionModel(
            headerTitle: "文件查询",
            rowList: [
                ListData(title: "查看文档", type: .documents),
                ListData(title: "查看政策", type: .documents)
            ]
        )
        self.sectionList = [infoSection, docSection]
    }
    
    // 支持自定义传入分组数据的扩展构造器
    init(customSections: [TableSectionModel]) {
        self.sectionList = customSections
    }
}

适配后的UITableView代理方法

// 初始化ViewModel
let viewModel = MyViewModel()

func numberOfSections(in tableView: UITableView) -> Int {
    return viewModel.sectionList.count
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return viewModel.sectionList[section].rowList.count
}

public func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    // 替换为你自己的headerView初始化逻辑
    let headerView = YourCustomHeaderView()
    headerView.titleLabel.text = viewModel.sectionList[section].headerTitle
    return headerView
}

// 附加cell配置示例逻辑,可直接复用
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "YourCellID", for: indexPath) as! YourCustomCell
    let rowData = viewModel.sectionList[indexPath.section].rowList[indexPath.row]
    cell.textLabel?.text = rowData.title
    // 可根据rowData.type差异化配置cell样式
    return cell
}

逻辑说明

  • 新增TableSectionModel将每个分组的header标题和对应行数据绑定,完全对齐UITableView的section-row数据结构,不会出现索引不匹配的问题
  • 所有数据逻辑都封装在ViewModel内部,ViewController只需要按索引取值即可,不需要处理业务逻辑,符合MVVM分层要求
  • 后续如果需要新增/删除分组、调整分组内的行数据,只需要修改ViewModel的构造逻辑即可,不需要修改代理层代码,可维护性更高

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 18:39:04