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'
相关产品推荐
相关产品推荐

