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

Swift中UICollectionViewCell背景颜色无法修改及JSON解码失败问题求助

Swift中UICollectionViewCell背景颜色无法修改及JSON解码失败问题求助

我来帮你一步步梳理这两个问题,逐个解决:


一、UICollectionViewCell背景颜色不生效的问题

问题根源

你现在是直接在didSelectItemAt里修改cell的背景色,但UICollectionView的cell是复用机制,滚动后之前的选中状态会丢失;而且你没有在cellForItemAt方法里根据选中状态重新设置背景色,导致cell始终显示Storyboard里预设的绿色。另外,用selectedNamesArray单独维护选中项的方式,没有和cell的展示逻辑绑定,很容易出现状态不同步的情况。

解决方案

结合你修改后的Datum模型,用模型的本地状态属性来管理选中状态,让cell的展示和模型数据强绑定:

  1. 在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
}
  1. 修改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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.21 13:42:57