UICollectionView 的不可见单元格未被取消选择 - Swift

Posted

技术标签:

【中文标题】UICollectionView 的不可见单元格未被取消选择 - Swift【英文标题】:Invisible cells of UICollectionView are not deselected - Swift 【发布时间】:2020-02-25 07:58:03 【问题描述】:

我的 swift 应用中有两个集合视图。一个是功能类别,另一个是功能。第一个用作第二个的过滤器。如果我选择“Cat1”,则只显示带有标签“Cat1”的函数。这很好用。 功能类别 collectionview 是水平的,我需要滚动查看所有单元格。我的问题/问题已在其他主题中提到,但我找不到正确的答案或技术。

问题:如果我选择一个类别,单元格的背景会改变,很好。如果现在我完全滚动到集合视图的末尾并选择最后一个单元格,则选择第一个(先前选择的)的这个更改不会取消选择。我知道这是重用单元格的问题,但不知道如何管理那。在我的代码下方:

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) 
// Working with functions categories collection view
      if collectionView == self.functionsCategoriesCollectionView 
          let cell = collectionView.cellForItem(at: indexPath) as! DevicePageFunctionsCategoriesCVCell
              cell.isHidden = false
              cell.cellView.isHidden = false
              cell.isSelected = true

              cell.cellView.clipsToBounds = true
              cell.cellView.layer.cornerRadius = 25
              cell.cellView.addGradiant(colors: [UIColor(red: 127.0/255.0, green: 127.0/255.0, blue: 127.0/255.0, alpha: 1.0).cgColor, UIColor(red: 47.0/255.0, green: 47.0/255.0, blue: 47.0/255.0, alpha: 1.0).cgColor], angle: 45)

          if cellSelectionIndexPath == indexPath 
              // it was already selected
              cellSelectionIndexPath = nil
              collectionView.deselectItem(at: indexPath, animated: true)
              cell.cellView.addGradiant(colors: [UIColor.clear.cgColor, UIColor.clear.cgColor], angle: 0)

              self.filtered = GlobalVariables.currentProduct.functions.filter  _ in
                  return true
              

              self.functionsCollectionView.reloadData()

           else 
              // wasn't yet selected, so let's remember it
              cellSelectionIndexPath = indexPath

              // Filter with seletec category name
              let cellCategoryName = ICDatabase.objects(FunctionCategory.self)[indexPath.row]

              self.filtered = GlobalVariables.currentProduct.functions.filter  function in
                  return function.functionCategory.contains(cellCategoryName)
              

              self.functionsCollectionView.reloadData()
          

      


func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) 

        if collectionView == self.functionsCategoriesCollectionView 

            if let cellToDeselect = collectionView.cellForItem(at: self.cellSelectionIndexPath) as? DevicePageFunctionsCategoriesCVCell 

                cellToDeselect.isSelected = false

                collectionView.deselectItem(at: self.cellSelectionIndexPath, animated: true)

                cellToDeselect.cellView.addGradiant(colors: [UIColor.clear.cgColor, UIColor.clear.cgColor], angle: 0)

                self.cellSelectionIndexPath = nil

                // Get all functions
                self.filtered = GlobalVariables.currentProduct.functions.filter  _ in
                    return true
                

                self.functionsCollectionView.reloadData()
            
        

感谢您的帮助!

【问题讨论】:

一如既往:管理数据模型中的选择,不要直接操作单元格。然后将在itemForRowAt 中可靠地设置正确的 UI 状态。其他一切都很麻烦且容易出错。 【参考方案1】:

试试这个 -

var selectedIndexPath: IndexPath?

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) 
        let cell = collectionView.cellForItem(at: indexPath)

        cell.layer.backgroundColor = UIColor.black

        self.selectedIndexPath = indexPath
    

    func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) 
        let cell = collectionView.cellForItem(at: indexPath)

        cell.layer.backgroundColor = UIColor.white

        self.selectedIndexPath = nil
    

【讨论】:

感谢您的帮助,但这与我的实际代码完全相同 @Silvering 你在 cellForItemAt(indexPath) 中做了什么 gist.github.com/MickaelCruzDB/22d11e657e7b24546759c874236f8127 我编辑了我的要点:gist.github.com/MickaelCruzDB/8bcd0c4c7bd29206f0dac6b2af2ad711【参考方案2】:

收集单元重用内存。所以你必须手动管理数据和 UI。如果您的要求是在任何时候只选择集合视图中的一个类别单元格,请在集合视图中保留一个变量并在 didSelect 方法中更新它。

var selectedIndexPath: IndexPath?

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) 
    selectedIndexPath = indexPath
    collectionView.reloadData()


func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
    let cell = UICollectionCell()
    ....
    cell.backgroundColor = UIColor.black
    if indexPath == selectedIndexPath 
        cell.backgroundColor = UIColor.red
     

【讨论】:

我根据您的建议创建了一个要点:gist.github.com/MickaelCruzDB/8bcd0c4c7bd29206f0dac6b2af2ad711 但我无法解决我的问题

以上是关于UICollectionView 的不可见单元格未被取消选择 - Swift的主要内容,如果未能解决你的问题,请参考以下文章

UICollectionView 单元格未在 reloadData 上清除

UICollectionView 自定义单元格未重新加载

UICollectionView 正在显示,但单元格未快速显示

UICollectionView estimatedItemSize - 最后一个单元格未对齐

UICollectionView 具有自调整大小的单元格未正确计算 contentSize

Xcode中集合视图的单元格未出现