UICollectionView Cell 在选择时不会改变

Posted

技术标签:

【中文标题】UICollectionView Cell 在选择时不会改变【英文标题】:UICollectionView Cell not changing upon selecting 【发布时间】: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 不会改变。

【问题讨论】:

【参考方案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

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

【讨论】:

以上是关于UICollectionView Cell 在选择时不会改变的主要内容,如果未能解决你的问题,请参考以下文章

UICollectionView 和 Selected Cell 在滚动时失去选择

在点击时切换 UICollectionView Cell 的选择/取消选择状态 - Swift

UICollectionView reloadData后cell被隐藏

UICollectionView 单元格没有选择翻转动画,视图丢失

我可以在 1 UICollectionView 中使用 collectionViewCell 2 Cell 吗?

UICollectionView的cell创建直接从第三个数据开始问题