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

Swift中指定UITableView显示对应数据源的最优实现方案

针对UITableView动态切换数据源的最优方案

嘿,作为Swift新手能想到扩展TableView的数据源切换逻辑,已经很棒啦!针对你的需求,我推荐一个清晰易维护、扩展性强的方案——通过「统一的当前数据源属性」来动态提供数据,让TableView的核心数据源方法不用写一堆分支判断,逻辑更简洁。

步骤1:定义显示模式枚举(替代布尔值,更清晰)

先创建一个枚举来标记当前的显示状态,比用isShowingAll这类布尔值可读性高很多,以后要加新的显示模式也更容易扩展:

enum SpendingDisplayMode {
    case permanentOnly // 仅显示固定支出
    case all // 显示全部支出
}

然后在你的TableViewControllerSpending里添加一个模式属性,并且在模式变化时自动刷新TableView:

class TableViewControllerSpending: UITableViewController, SpendingProtocol {
    // 你的两个原始数据源数组
    var spendingsTemporary : [Spending] = [Spending(title: "Shoes", amount: 245.99, date: Date())]
    var spendingsPermanent : [Spending] = [Spending(title: "Taxes", amount: 125.50, date: Date())]
    
    // 当前显示模式,默认显示全部
    var currentDisplayMode: SpendingDisplayMode = .all {
        didSet {
            // 模式切换时自动刷新表格
            tableView.reloadData()
            // 可以顺便更新导航栏标题,提升用户体验
            title = currentDisplayMode == .all ? "全部支出" : "我的固定支出"
        }
    }
    
    // ... 其他代码
}

步骤2:创建「当前显示数据源」的计算属性

用一个计算属性根据当前模式返回对应的数据,这样TableView的所有数据源方法只需要依赖这个属性:

var currentSpendings: [Spending] {
    switch currentDisplayMode {
    case .permanentOnly:
        return spendingsPermanent
    case .all:
        // 合并两个数组,顺序可以根据需求调整
        return spendingsTemporary + spendingsPermanent
    }
}

步骤3:修改TableView数据源方法,统一使用currentSpendings

把原来依赖spendingsTemporary或spendingsPermanent的地方,全部换成currentSpendings:

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return currentSpendings.count
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    // 假设你的cell复用ID是"SpendingCell"
    let cell = tableView.dequeueReusableCell(withIdentifier: "SpendingCell", for: indexPath)
    let spending = currentSpendings[indexPath.row]
    
    // 配置cell内容
    cell.textLabel?.text = spending.title
    cell.detailTextLabel?.text = String(format: "$%.2f", spending.amount)
    // 如果需要显示日期,可以在这里处理格式化
    return cell
}

步骤4:处理按钮点击,切换显示模式

给导航栏的按钮添加点击事件,直接修改currentDisplayMode即可:

@IBAction func showPermanentSpendingsTapped(_ sender: UIBarButtonItem) {
    currentDisplayMode = .permanentOnly
}

@IBAction func showAllSpendingsTapped(_ sender: UIBarButtonItem) {
    currentDisplayMode = .all
}

额外优化建议

  • 如果两个数组可能存在重复数据,需要去重的话,可以让Spending结构体遵守Hashable协议,然后在all模式下用Set去重(注意Set会打乱顺序,需要保持顺序的话可以自己实现去重逻辑):
struct Spending: Hashable { 
    var title: String 
    var amount: Float 
    var date: Date? 
}

// 修改currentSpendings的all分支
case .all:
    return Array(Set(spendingsTemporary + spendingsPermanent))
  • 后续如果要新增「仅显示临时支出」的模式,只需要给SpendingDisplayMode加一个case temporaryOnly,然后在currentSpendings里添加对应分支即可,扩展性拉满。

内容的提问来源于stack exchange,提问作者Alejandro El Venatch'

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:19:16