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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:38:01