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

iOS Swift中TableViewCell自定义按钮单选功能异常排查

问题排查与修复方案

问题根源

  1. 单选逻辑选型错误:用数组selectedRows处理单选需求冗余且容易引发逻辑混乱,单选场景只需记录单个选中行号即可。
  2. UI更新逻辑错误:闭包中直接操作当前cell的按钮状态,未考虑TableView的复用机制,导致已选中的旧cell无法同步更新状态。
  3. 数组操作异常:遍历selectedRows时直接删除元素,会触发数组遍历过程中修改的越界问题,同时重复的条件判断导致UI状态混乱。
  4. 未处理取消选中场景:原代码仅处理“未选中时添加”的情况,缺失重复点击取消选中的逻辑。

修复后的代码实现

1. 替换选中状态存储变量

将原数组selectedRows替换为单个可选整数,简化单选状态管理:

// 记录当前选中的行号,nil表示无选中项
var selectedRow: Int?

2. 修正cellForRowAt方法

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "你的Cell标识符", for: indexPath) as! YourTableViewCell
    
    // 绑定行号到按钮tag
    cell.buttonRadio.tag = indexPath.row
    
    // 初始化时根据选中状态设置按钮图标(适配cell复用)
    let isCurrentSelected = selectedRow == indexPath.row
    cell.buttonRadio.setImage(UIImage(named: isCurrentSelected ? "radioSelected" : "radioUnselected"), for: .normal)
    
    // 按钮点击事件处理
    cell.selectCategory = { [weak self] tappedRow in
        guard let self = self else { return }
        
        // 单选逻辑:点击已选中行则取消,否则切换选中当前行
        if self.selectedRow == tappedRow {
            self.selectedRow = nil
        } else {
            self.selectedRow = tappedRow
        }
        
        // 更新底部按钮状态
        let hasSelectedItem = self.selectedRow != nil
        self.buttonLink.isUserInteractionEnabled = hasSelectedItem
        self.buttonLink.backgroundColor = hasSelectedItem ? UIColor(hex: "#453073") : UIColor(hex: "#A297B9")
        
        // 刷新受影响的行,确保所有cell状态同步
        if let previousRow = self.selectedRow {
            tableView.reloadRows(at: [IndexPath(row: previousRow, section: 0)], with: .automatic)
        }
        tableView.reloadRows(at: [IndexPath(row: tappedRow, section: 0)], with: .automatic)
    }
    
    return cell
}

3. TableViewCell代码保持不变

你的Cell代码无需修改,继续使用:

var selectCategory: ((Int) -> Void)?

@IBAction func didTapSelected(_ sender: UIButton) {
    selectCategory?(sender.tag)
}

关键修复点说明

  • 用单个变量替代数组,彻底简化单选逻辑,避免数组操作的潜在bug。
  • 在cellForRowAt中直接根据选中状态初始化按钮图标,适配TableView的cell复用机制,确保每次cell复用都能显示正确状态。
  • 通过reloadRows刷新受影响的行,解决了原代码中仅更新当前cell、旧选中cell状态不更新的问题。
  • 使用[weak self]避免循环引用,防止内存泄漏。
  • 增加了重复点击取消选中的逻辑(若不需要该功能,可直接将逻辑改为self.selectedRow = tappedRow)。

内容的提问来源于stack exchange,提问作者Shaikh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 01:45:40