Swift中UICollectionViewCell背景颜色无法修改及JSON解码失败问题求助
Swift中UICollectionViewCell背景颜色无法修改及JSON解码失败问题求助
我来帮你一步步梳理这两个问题,逐个解决:
一、UICollectionViewCell背景颜色不生效的问题
问题根源
你现在是直接在didSelectItemAt里修改cell的背景色,但UICollectionView的cell是复用机制,滚动后之前的选中状态会丢失;而且你没有在cellForItemAt方法里根据选中状态重新设置背景色,导致cell始终显示Storyboard里预设的绿色。另外,用selectedNamesArray单独维护选中项的方式,没有和cell的展示逻辑绑定,很容易出现状态不同步的情况。
解决方案
结合你修改后的Datum模型,用模型的本地状态属性来管理选中状态,让cell的展示和模型数据强绑定:
- 在
cellForItemAt里根据模型的isSelected状态设置背景色:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "TestCollectionCell", for: indexPath) as! TestCollectionCell cell.layoutIfNeeded() guard let datum = jsonData?.data[indexPath.row] else { return cell } cell.titleLbl.text = datum.name // 根据模型选中状态设置背景色 cell.backgroundColor = datum.isSelected ? .yellow : .systemGreen // 这里的默认色可以换成你想要的初始颜色 return cell }
- 修改
didSelectItemAt方法,不再直接修改cell,而是更新模型状态并刷新对应cell:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { guard var dataArray = jsonData?.data else { return } // 切换当前项的选中状态 dataArray[indexPath.row].isSelected = !dataArray[indexPath.row].isSelected jsonData?.data = dataArray // 仅刷新当前选中的cell,性能更优 collectionView.reloadItems(at: [indexPath]) // 如果你还需要获取选中的名字数组,可以直接从模型里过滤 let selectedNames = dataArray.filter { $0.isSelected }.map { $0.name } print(selectedNames) }
这样修改后,cell的背景色会和模型状态完全同步,即使cell被复用也不会丢失选中状态。
二、JSON解码失败的问题
问题根源
你在Datum模型里把isSelected加入了CodingKeys,并映射到is_selected字段,但请求的API返回数据里根本没有这个字段,所以解码时系统找不到对应key就会报错。isSelected是你本地用来标记状态的属性,不需要从服务器返回的数据中解码。
解决方案
把isSelected移出CodingKeys,让它作为本地默认属性存在:
// MARK: - Datum struct Datum: Codable { let id: Int let name: String let year: Int let color, pantoneValue: String // 本地状态属性,不参与JSON解码/编码,给默认值false var isSelected: Bool = false enum CodingKeys: String, CodingKey { case id, name, year, color case pantoneValue = "pantone_value" // 移除isSelected对应的key,让系统忽略这个属性的解码 } }
这样修改后,解码时系统会自动忽略isSelected属性,用默认值false初始化,就不会出现解码失败的错误了。
备注:内容来源于stack exchange,提问作者new dev
相关产品推荐
相关产品推荐

