UICollectionView单元格选中状态颜色切换实现问题
UICollectionView单选高亮逻辑修复方案
现有代码核心问题
- 单选场景冗余变量过多,
selectedItems、selectedItem、previousIndex多变量同步状态极易出错 IndexPath初始化方式错误,单分区列表使用IndexPath(index:)无法定位到正确单元格,会导致旧选中项样式重置失败- 单元格样式逻辑分散,在
didSelectItemAt中手动修改cell属性的方式,会在Cell复用时出现样式错乱 - 默认选中逻辑缺失,首次加载时没有统一的状态判断入口,首项高亮无法稳定显示
修正后实现
1. 精简状态变量
初始值直接设为0,对应首项"All Venues"默认选中:
// 仅保留当前选中索引,默认选中第0位的All Venues var currentSelectedIndex = 0 var searchIsActive = false
2. 统一单元格样式逻辑
所有样式判断全部收敛到cellForItemAt中,避免手动改Cell属性导致的状态不一致:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "FilterCollectionViewCell", for: indexPath) as! FilterCollectionViewCell cell.nameLabel.text = collectionViewArray[indexPath.row].name // 仅根据当前选中索引渲染样式 if indexPath.row == currentSelectedIndex { cell.filterContainerView.backgroundColor = UIColor(hexString: "001A38") cell.nameLabel.textColor = .white cell.isHighlightedCell = true } else { cell.filterContainerView.backgroundColor = .clear cell.nameLabel.textColor = .black cell.isHighlightedCell = false } return cell }
3. 简化点击选中逻辑
点击时只更新选中索引,通过reloadItems触发单元格样式刷新,不直接操作Cell属性:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { // 点击已选中项直接返回 guard indexPath.row != currentSelectedIndex else { return } // 记录旧选中项位置,更新当前选中索引 let oldSelectedIndexPath = IndexPath(row: currentSelectedIndex, section: 0) currentSelectedIndex = indexPath.row let selectedName = collectionViewArray[currentSelectedIndex].name ?? "" // 刷新新旧两个单元格,自动应用样式 collectionView.reloadItems(at: [oldSelectedIndexPath, indexPath]) // 关联业务逻辑 searchIsActive = selectedName != "All Venues" barsShown = searchIsActive ? barArray.filter { $0.type == selectedName } : barArray barDisplayedTableView.reloadData() updateAnimationForTableView() }
4. 首次加载适配
页面数据初始化完成后调用一次collectionView.reloadData(),即可自动渲染首项"All Venues"的默认高亮效果。
内容的提问来源于stack exchange,提问作者WhySoSerious33
相关产品推荐
相关产品推荐

