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

CollectionView单元格滚动/点击后Alpha属性丢失问题求助

问题:CollectionView单元格置灰Alpha值滚动后丢失,交互状态保留

我用CollectionView展示设备状态,把无货设备的单元格Alpha设为0.2实现置灰效果,但滚动屏幕或点击单元格后,单元格重载时Alpha设置丢失,原本置灰的单元格恢复正常透明度,不过cell.userInteractionEnabled的设置能正常保留。

相关实现代码

CollectionView数据源方法

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = myCollectionView.dequeueReusableCell(withReuseIdentifier: "MyCollectionViewCell", for: indexPath) as! MyCollectionViewCell
        self.allDevices = self.allDevices.sorted(by: {$0.givenName.lowercased() < $1.givenName.lowercased()})
    
    DispatchQueue.main.async {
        let deviceSKU = self.allDevices[indexPath.row].name
        let deviceName = self.allDevices[indexPath.row].givenName
        var alphaValue = 1.0
        var enableValue = true
        if self.allDevices[indexPath.row].connectFlag != nil {
            alphaValue = (self.allDevices[indexPath.row].connectFlag == "1") ? 1.0 : 0.2
            enableValue = (self.allDevices[indexPath.row].connectFlag == "1") ? true : false
        }

        if deviceSKU == "STS001" {
            let deviceImage = (self.allDevices[indexPath.row].state == true) ? UIImage(named: "socket-green.png") : UIImage(named: "socket-red.png")
            cell.configure(with: deviceImage!, name: deviceName, offline: alphaValue, enabled: enableValue)
        }
        if deviceSKU == "DWS01" {
            let deviceImage = (self.allDevices[indexPath.row].state == true) ? UIImage(named: "door-close2.png") : UIImage(named: "door-open2.png")
                    cell.configure(with: deviceImage!, name: deviceName, offline: alphaValue, enabled: enableValue)
            
        }
        
        if deviceSKU == "BWS01" {
            let deviceImage = (self.allDevices[indexPath.row].state == true) ? UIImage(named: "wallsocket-on.png") : UIImage(named: "wallsocket-off.png")
            cell.configure(with: deviceImage!, name: deviceName, offline: alphaValue, enabled: enableValue)
            
        }
        
        if deviceSKU == "5CHN" {
            let deviceImage = UIImage(named: "5Channel.png")
            cell.configure(with: deviceImage!, name: deviceName, offline: alphaValue, enabled: enableValue)
            
        }

    }
    
        return cell
    
 }

UICollectionViewCell的configure函数

public func configure(with image: UIImage, name: String, offline : CGFloat, enabled : Bool){
    deviceImage.image = image
    deviceName.text = name
    self.alpha = offline
    self.isUserInteractionEnabled = enabled
}

解决方案

问题根源

  1. cellForItemAt本身运行在主线程,你额外嵌套了DispatchQueue.main.async,导致单元格配置延迟。CollectionView的复用机制会在异步块执行前就将单元格返回并渲染,滚动或重载时,新复用的单元格可能还没等到Alpha设置就已经显示,导致置灰效果丢失。
  2. 每次单元格复用都对allDevices数组排序,会导致数据源顺序不稳定,干扰配置逻辑的准确性。

修复步骤

  1. 移除不必要的异步块:直接在cellForItemAt中同步配置单元格。
  2. 提前排序数据源:在获取到设备数据后统一排序,不要每次复用单元格都执行排序。
  3. 优化SKU判断逻辑:用switch替代多个if,提升代码可读性和维护性。

修改后的代码

调整后的数据源方法
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = myCollectionView.dequeueReusableCell(withReuseIdentifier: "MyCollectionViewCell", for: indexPath) as! MyCollectionViewCell
    
    // 直接取对应位置的设备数据
    let device = allDevices[indexPath.row]
    let deviceSKU = device.name
    let deviceName = device.givenName
    var alphaValue: CGFloat = 1.0
    var enableValue = true
    
    // 处理置灰和交互状态
    if let connectFlag = device.connectFlag {
        alphaValue = connectFlag == "1" ? 1.0 : 0.2
        enableValue = connectFlag == "1"
    }
    
    // 根据SKU获取对应图片
    var deviceImage: UIImage!
    switch deviceSKU {
    case "STS001":
        deviceImage = device.state ? UIImage(named: "socket-green.png") : UIImage(named: "socket-red.png")
    case "DWS01":
        deviceImage = device.state ? UIImage(named: "door-close2.png") : UIImage(named: "door-open2.png")
    case "BWS01":
        deviceImage = device.state ? UIImage(named: "wallsocket-on.png") : UIImage(named: "wallsocket-off.png")
    case "5CHN":
        deviceImage = UIImage(named: "5Channel.png")
    default:
        deviceImage = UIImage() // 可设置默认占位图
    }
    
    // 同步配置单元格
    cell.configure(with: deviceImage, name: deviceName, offline: alphaValue, enabled: enableValue)
    
    return cell
}
数据源排序的正确位置

在获取到设备数据后执行排序,再刷新CollectionView:

// 示例:获取设备数据完成后排序
allDevices = allDevices.sorted(by: {$0.givenName.lowercased() < $1.givenName.lowercased()})
myCollectionView.reloadData()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 20:05:35