Swift实现TableView单元格数值增减及总和计算的代码需求
嘿,我来帮你搞定这个Swift的TableView求和功能问题~你的现有实现存在几个可以优化的点,比如8个重复的Cell类完全没必要,而且当前ViewController没法直接获取每个Cell的数值来计算总和。下面是两种解决方案,优先推荐更简洁易维护的重构方案:
推荐方案:重构为通用Cell+数据源管理
这种方式能大幅减少冗余代码,同时保证数据一致性,是iOS开发的常规做法。
1. 创建通用的自定义Cell类
把8个重复的Cell类替换成一个CounterTableViewCell,统一处理计数逻辑,并通过代理把数值变化通知给ViewController:
import UIKit // 定义代理协议,用于Cell向ViewController传递数值变化 protocol CounterTableViewCellDelegate: AnyObject { func counterCell(_ cell: CounterTableViewCell, didUpdateCount count: Int, at indexPath: IndexPath?) } class CounterTableViewCell: UITableViewCell { @IBOutlet weak var countLabel: UILabel! weak var delegate: CounterTableViewCellDelegate? var indexPath: IndexPath? private var currentCount = 1 { didSet { countLabel.text = "\(currentCount)" // 数值变化时通知ViewController delegate?.counterCell(self, didUpdateCount: currentCount, at: indexPath) } } override func awakeFromNib() { super.awakeFromNib() // 初始化显示默认值1 countLabel.text = "\(currentCount)" } @IBAction func minusTapped(_ sender: Any) { if currentCount > 1 { currentCount -= 1 } } @IBAction func addTapped(_ sender: Any) { currentCount += 1 } // 供ViewController设置初始/更新数值的方法 func setCount(_ count: Int) { currentCount = count } }
2. 修改ViewController实现
ViewController维护一个数据源数组来记录所有Cell的当前数值,实现代理方法同步数据,最后完成求和逻辑:
import UIKit class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, CounterTableViewCellDelegate { @IBOutlet weak var tableviewObj: UITableView! @IBOutlet weak var labelObj: UILabel! // 数据源:存储8个Cell的数值,初始值全为1 private var countsArray = Array(repeating: 1, count: 8) override func viewDidLoad() { super.viewDidLoad() tableviewObj.dataSource = self tableviewObj.delegate = self // 如果是通过XIB创建的Cell,记得注册(Storyboard拖的Cell可忽略) tableviewObj.register(UINib(nibName: "CounterTableViewCell", bundle: nil), forCellReuseIdentifier: "CounterCell") } func numberOfSections(in tableView: UITableView) -> Int { return 1 } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return countsArray.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "CounterCell", for: indexPath) as! CounterTableViewCell cell.delegate = self cell.indexPath = indexPath cell.setCount(countsArray[indexPath.row]) return cell } // 实现代理方法,更新数据源数组 func counterCell(_ cell: CounterTableViewCell, didUpdateCount count: Int, at indexPath: IndexPath?) { guard let indexPath = indexPath else { return } countsArray[indexPath.row] = count } @IBAction func Total(_ sender: Any) { // 用reduce快速计算数组总和 let total = countsArray.reduce(0, +) labelObj.text = "总和:\(total)" } }
关键优化点:
- 用
countsArray统一管理所有Cell的数值,避免依赖Cell内部的私有变量 - 通过代理模式保证Cell的数值变化实时同步到数据源,数据一致性更强
- 求和逻辑简洁高效,不用遍历Cell,直接操作数据源数组
备选方案:不重构现有Cell类的修复方式
如果暂时不想修改现有8个Cell的结构,也可以通过以下方式实现求和,但这种方式代码冗余、维护成本高,不推荐长期使用:
1. 给每个Cell类添加获取数值的公共方法
以firstTableViewCell为例,其他7个Cell类做同样修改:
class firstTableViewCell: UITableViewCell { @IBOutlet var labelObj: UILabel! var cur = 1 // 初始化默认值为1 override func awakeFromNib() { super.awakeFromNib() labelObj.text = "\(cur)" // 初始化显示 } @IBAction func Minus(_ sender: Any) { if cur > 1 { cur -= 1 labelObj.text = "\(cur)" } } @IBAction func Add(_ sender: Any) { cur += 1 labelObj.text = "\(cur)" } // 添加公共方法,让ViewController能获取当前数值 func getCurrentCount() -> Int { return cur } }
2. 完善ViewController的求和方法
遍历所有Cell,逐个转换类型并获取数值求和:
@IBAction func Total(_ sender: Any) { var total = 0 for row in 0..<8 { let indexPath = IndexPath(row: row, section: 0) guard let cell = tableviewObj.cellForRow(at: indexPath) else { continue } switch row { case 0: total += (cell as! firstTableViewCell).getCurrentCount() case 1: total += (cell as! secondTableViewCell).getCurrentCount() case 2: total += (cell as! thirdTableViewCell).getCurrentCount() case 3: total += (cell as! fourthTableViewCell).getCurrentCount() case 4: total += (cell as! fifthTableViewCell).getCurrentCount() case 5: total += (cell as! sixthTableViewCell).getCurrentCount() case 6: total += (cell as! seventhTableViewCell).getCurrentCount() case 7: total += (cell as! eighthTableViewCell).getCurrentCount() default: break } } labelObj.text = "总和:\(total)" }
内容的提问来源于stack exchange,提问作者chandra1234
相关产品推荐
相关产品推荐

