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

点击UICollectionView切换图片位置错误、多选异常问题排查

问题根因

  • 单选逻辑缺失:点击按钮时仅修改了当前点击项的选中状态,未将之前选中的项的isImageSelected重置为false,导致多个项同时被标记为选中
  • UI状态与数据源不同步:你直接在点击方法中修改按钮的图片,但是在cellForItemAt复用cell时仅设置了logoButton.isSelected,没有同步设置按钮图片,cell复用后就会出现图片显示错乱
  • 重复添加点击事件:每次cell复用都会给按钮添加一次点击回调,多次复用后点击按钮会触发多次逻辑,进一步导致状态混乱

修复方案

推荐优先使用UICollectionView自带的选中回调实现,避免tag、重复添加事件等问题,修改后代码如下:

1. 优化cell复用逻辑

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let teamSelection = self.teamCollectionView.dequeueReusableCell(withReuseIdentifier: "teamCell", for: indexPath) as! TeamSelectionCollectionViewCell
    let row = teamSelectionList[indexPath.row]
    teamSelection.logoImage.image = UIImage(named: row.logoImage)
    // 所有UI状态完全从数据源读取,不要在其他地方直接修改UI控件状态
    if row.isImageSelected {
        teamSelection.logoButton.setImage(UIImage(named: "ic_radio_selected"), for: .normal)
    } else {
        teamSelection.logoButton.setImage(UIImage(named: "ic_radio_normal"), for: .normal)
    }
    // 禁用按钮单独响应,统一交给cell选中事件处理
    teamSelection.logoButton.isUserInteractionEnabled = false
    teamSelection.seperatorView.isHidden = indexPath.row == 2 || indexPath.row == self.teamSelectionList.count - 1
    return teamSelection
}

2. 新增collectionView选中回调,替换原有的按钮点击方法

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    // 先重置上一个选中项的状态
    if currentIndex != indexPath.row {
        teamSelectionList[currentIndex].isImageSelected = false
    }
    // 切换当前点击项的选中状态
    teamSelectionList[indexPath.row].isImageSelected.toggle()
    // 更新当前选中下标
    currentIndex = indexPath.row
    // 刷新列表同步UI
    teamCollectionView.reloadData()
}

如果你需要保留按钮点击的实现,做如下修改即可:

  1. 在cellForItemAt添加target前先移除旧的回调,避免重复触发:
teamSelection.logoButton.removeTarget(self, action: #selector(logoButtonTapped), for: .touchUpInside)
teamSelection.logoButton.tag = indexPath.row
teamSelection.logoButton.addTarget(self, action: #selector(logoButtonTapped), for: .touchUpInside)
  1. 修改按钮点击逻辑:
@objc func logoButtonTapped(sender: UIButton){
    let tapIndex = sender.tag
    // 重置上一个选中项状态
    if currentIndex != tapIndex {
        teamSelectionList[currentIndex].isImageSelected = false
    }
    // 切换当前项选中状态
    teamSelectionList[tapIndex].isImageSelected.toggle()
    currentIndex = tapIndex
    teamCollectionView.reloadData()
}

内容的提问来源于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 15:24:03