【问题标题】:UICollectionView Cell not changing upon selectingUICollectionView Cell 在选择时不会改变
【发布时间】:2019-01-09 02:34:08
【问题描述】:

在我的项目中,我有一个 UICollectionView。在 UICollectionView 中,我有一个自定义单元格。

当在“didSelectItemAt”中选择单元格值时,我可以打印它,但是,如果我尝试在此方法中以任何方式编辑单元格,它不会改变。

我确定我遗漏了一些东西,任何帮助将不胜感激!

@IBOutlet weak var collectionView: UICollectionView!

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return statValues.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "customCollectionViewCell", for: indexPath) as! customCollectionViewCell

    cell.statLabel.text = statHeaders[indexPath.row]
    cell.statLabel.textColor = UIColor(red:0.31, green:0.31, blue:0.31, alpha:1.0)

    return cell
}

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "customCollectionViewCell", for: indexPath) as! customCollectionViewCell

    print(cell.statLabel.text)
    cell.backgroundColor = UIColor.yellow
    collectionView.reloadData()

}

当用户选择一个单元格时,代码会正确打印 indexPath 的值,但是 backgroundColor 不会改变。

【问题讨论】:

    标签: swift uicollectionview uicollectionviewcell


    【解决方案1】:

    我的猜测是您正在创建一个新的单元格实例,而不是使用 collectionView 中的那个

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        // Change this line
        let cell = collectionView.cellForItemAtIndexPath(indexPath: indexPath)
    
        print(cell.statLabel.text)
        cell.backgroundColor = UIColor.yellow
        collectionView.reloadData()
    
    }
    

    此外,您可能应该为您的事实来源保留一个外部数据模型。如果您有足够多的需要滚动的 collectionView,当您在屏幕外滚动时,您的单元格将以随机顺序重复使用,导致您未点击的单元格变为黄色。

    创建一个单独的数组如

    var selectedStatHeaders: Set<Int>()
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "customCollectionViewCell", for: indexPath) as! customCollectionViewCell
    
        cell.statLabel.text = statHeaders[indexPath.row]
        cell.statLabel.textColor = UIColor(red:0.31, green:0.31, blue:0.31, alpha:1.0)
        // Reset/configure cell each reload
        if selectedStatHeaders.contains(indexPath.row) { // Can also make this into a ternary
          cell.backgroundColor = UIColor.yellow
        } else {
          cell.backgroundColor = UIColor.whit
        }
        return cell
    }
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        selectedStatHeaders.insert(indexPath.row)
        collectionView.reloadItemsAtIndexPath(indexPath: indexpath)
    }
    

    【讨论】:

    • 这应该可以,也不需要调用reloadData,应该使用reloadItems。
    • ^ 编辑以获得更好的答案
    • 另外,只是一个建议,每当使用单元格被重用的 tableviews/collectionview 时,您应该缓存颜色而不是在 cellforRow/Item 中调用 UIColor(),因为这会被多次调用并且可能会导致内存问题。
    • 这个解决方案奏效了!我确实在创建一个新的单元格实例,而不是使用 collectionView 中的那个,我知道我遗漏了一些东西,谢谢@Mocha
    【解决方案2】:

    嗯...如果代码能够打印但背景不改变颜色,那就没有意义了。你的意思是从黄色变回白色?无论如何,只是一种预感,但我怀疑这是因为您在设置 backgroundColor 更改后调用了collectionView.reloadData()

    https://developer.apple.com/documentation/uikit/uicollectionview/1618078-reloaddata

    这会导致集合视图丢弃任何当前可见的 项目(包括占位符)并根据当前重新创建项目 数据源对象的状态。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多