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

UICollectionViewCell中Radio Button点击后无法取消其他选中项问题

问题根因

你当前的实现默认是多选逻辑,使用Set存储所有被选中的下标,新增选中项时不会清空旧的选中记录,因此会出现多个按钮同时选中的问题。此外你定义的TeamSelected结构体中的isImageSelected字段完全没有被使用,所有选中状态都通过外部的selection变量判断,属于冗余字段,容易引发状态不一致问题。

修复方案

对核心逻辑做如下修改即可实现单选效果:

  1. 替换选中状态存储变量
    将原有的Set类型的选中存储变量改为可选Int类型,单选场景下最多仅会有一个选中项,用可选类型更合适:
// 替换原有的 var selection = Set<Int>()
var selectedIndex: Int?
  1. 修改cellForItemAt中的选中判断逻辑
    将原有的Set包含判断改为相等判断:
// 替换原有的 let isImageSelected = selection.contains(index)
let isImageSelected = selectedIndex == index
  1. 修改按钮点击响应逻辑
    点击新的选项时直接覆盖选中下标即可:
@objc func logoButtonTapped(sender: UIButton){
    let index = sender.tag
    // 如果需要支持点击已选中项取消选中,保留if分支,不需要则直接赋值selectedIndex = index即可
    if selectedIndex == index {
        selectedIndex = nil
    } else {
        selectedIndex = index
    }
    self.teamCollectionView.reloadData()
}
优化建议
  • 避免重复绑定点击事件:UICollectionViewCell存在复用机制,你每次调用cellForItemAt都会给按钮添加一次target,多次复用后同一个按钮会绑定多个响应方法,点击时会触发多次回调。建议将addTarget逻辑移到TeamSelectionCollectionViewCell的初始化方法中,通过闭包或者代理将点击事件传递到外层处理,比使用tag存储下标更安全,避免列表增删元素后tag不准的问题。
  • 优化刷新性能:不需要每次点击都全量刷新整个CollectionView,仅需要刷新上一次选中的和当前选中的两个cell即可,性能更好:
@objc func logoButtonTapped(sender: UIButton){
    let index = sender.tag
    // 记录之前的选中下标
    let oldIndex = selectedIndex
    if selectedIndex == index {
        selectedIndex = nil
    } else {
        selectedIndex = index
    }
    // 仅刷新需要更新的cell
    var reloadPaths = [IndexPath(row: index, section: 0)]
    if let old = oldIndex, old != index {
        reloadPaths.append(IndexPath(row: old, section: 0))
    }
    self.teamCollectionView.reloadItems(at: reloadPaths)
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 23:36:04