Swift 如何计算UITableViewCell中选中按钮的数值总和
现有实现的核心问题
- 代理归属错误:两类Cell都是列表的子视图,没有直接绑定关系,无法将所有
ToggleNumberCell的代理都指向同一个CalculateCell实例,导致回调无法正确收集所有选中值。 - 数值存储逻辑错误:当前
CalculateCell的increment变量是直接赋值,每次新的选中值会覆盖旧值,无法累加多个Cell的选择结果。 - 缺少同Cell内按钮互斥逻辑:点击同个Cell的多个按钮会同时处于选中状态,导致数值回调错误。
正确实现方案
整体逻辑调整为:由持有TableView的ViewController统一管理所有选中值,接收ToggleNumberCell的选择回调,再响应CalculateCell的计算请求汇总结果。
1. 调整ToggleNumberCell逻辑
新增cell索引属性,补充同Cell内按钮互斥逻辑:
protocol ToggleNumberCellDelegate: AnyObject { func toggleNumberCell(_ toggleNumberCell: ToggleNumberCell, selectedValue: Int) } class ToggleNumberCell: UITableViewCell { static let reuseIdentifier = String(describing: ToggleNumberCell.self) // 新增属性,标记当前cell对应列表的行号 var cellIndex: Int = 0 @IBOutlet private weak var titleLabel: UILabel! @IBOutlet private weak var zeroButton: UIButton! @IBOutlet private weak var oneButton: UIButton! @IBOutlet private weak var twoButton: UIButton! @IBOutlet private weak var threeButton: UIButton! @IBOutlet private weak var fourButton: UIButton! @IBOutlet private weak var fiveButton: UIButton! @IBOutlet private weak var sixButton: UIButton! private weak var delegate: ToggleNumberCellDelegate? private var value: Int? @IBAction func buttonTapped(_ sender: UIButton) { // 先重置所有按钮为未选中样式 [zeroButton, oneButton, twoButton, threeButton, fourButton, fiveButton, sixButton].forEach { btn in btn?.backgroundColor = .white // 替换为你的未选中背景色 btn?.tintColor = .black // 替换为你的未选中文字色 } // 再设置当前点击按钮的选中样式 switch sender { case zeroButton: zeroButton.backgroundColor = UIColor.NBABlue zeroButton.tintColor = .white value = 0 case oneButton: oneButton.backgroundColor = UIColor.NBABlue oneButton.tintColor = .white value = 1 case twoButton: twoButton.backgroundColor = UIColor.NBABlue twoButton.tintColor = .white value = 2 // 剩余其他按钮的case同理补充 default: break } delegate?.toggleNumberCell(self, selectedValue: value!) print("选中的数值为\(value!)") } }
2. 调整CalculateCell逻辑
移除不必要的代理实现,新增计算按钮点击闭包回调:
class CalculateCell: UITableViewCell { static let reuseIdentifier = String(describing: CalculateCell.self) // 新增计算按钮点击回调闭包 var calculateButtonTapped: (() -> Void)? @IBOutlet private weak var calculateButton: UIButton! @IBOutlet private weak var totalLabel: UILabel! func configure(answer: AnswerModel) { self.backgroundColor = UIColor.secondarySystemGroupedBackground self.totalLabel.text = answer.text self.totalLabel.font = .preferredFont(forTextStyle: .headline) calculateButton.layer.cornerRadius = 10.0 } override func prepareForReuse() { super.prepareForReuse() self.totalLabel.text = nil } @IBAction func calculateTapped(_ sender: UIButton) { calculateButtonTapped?() } }
3. ViewController层统一管理数据
持有TableView的ViewController遵循ToggleNumberCellDelegate,维护所有选中值,处理计算请求:
class YourViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, ToggleNumberCellDelegate { // 按实际需求修改NumberCell的数量 private let numberCellTotalCount = 3 // 存储每个NumberCell的选中值,默认未选中为nil private var selectedValues: [Int?] = Array(repeating: nil, count: numberCellTotalCount) func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { if indexPath.row < numberCellTotalCount { let cell = tableView.dequeueReusableCell(withIdentifier: ToggleNumberCell.reuseIdentifier, for: indexPath) as! ToggleNumberCell cell.delegate = self cell.cellIndex = indexPath.row // 其他cell配置逻辑 return cell } else { let cell = tableView.dequeueReusableCell(withIdentifier: CalculateCell.reuseIdentifier, for: indexPath) as! CalculateCell // 监听计算按钮点击 cell.calculateButtonTapped = { [weak self] in guard let self = self else { return } // 汇总所有非空的选中值 let total = self.selectedValues.compactMap { $0 }.reduce(0, +) cell.totalLabel.text = "\(total)" } // 其他cell配置逻辑 return cell } } // 接收NumberCell的选中回调,更新存储的选中值 func toggleNumberCell(_ toggleNumberCell: ToggleNumberCell, selectedValue: Int) { selectedValues[toggleNumberCell.cellIndex] = selectedValue } }
内容的提问来源于stack exchange,提问作者isaacthedev
相关产品推荐
相关产品推荐

