【问题标题】:Deselect UICollectionView cell on second tap在第二次点击时取消选择 UICollectionView 单元格
【发布时间】:2017-12-13 13:54:18
【问题描述】:

我的项目应用程序中有 tableViews 和 collectionViews。在表格和集合中,我希望在第一次点击时选择行/单元格,并在第二次点击时取消选择。

通过tableView,我找到了一个相当简单明了的解决方案here,效果很好。

另一方面,CollectionView 被证明是完全不同类型的野兽。与 tableView 不同的是,没有willSelectItemAt 委托方法,因此无法在第二次点击注册之前检查项目是否处于选中状态。实现 shouldDeselectItemAtdidDeselectItemAt 不会产生任何结果 - 这些方法永远不会在点击时已被选中的单元格上调用。

唯一可行的solution 建议为每个collectionView 单元格创建一个UIButton,但它真的应该那么复杂吗?

【问题讨论】:

    标签: swift uicollectionview


    【解决方案1】:

    尝试使用“shouldSelectItem”UIColllectionViewDelegate 方法。

    func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {
        let item = collectionView.cellForItem(at: indexPath)
        if item?.isSelected ?? false {
            collectionView.deselectItem(at: indexPath, animated: true)
        } else {
            collectionView.selectItem(at: indexPath, animated: true, scrollPosition: [])
            return true
        }
    
        return false
    }
    

    【讨论】:

    • 谢谢,很好的解决方案!对于else 语句,我使用return true 而不是selectItem(),因为我需要在didSelectItemAt() 方法中完成一些逻辑,现在它可以按预期完成工作)
    【解决方案2】:

    @pkorosecanswer 的较短版本,具有完全相同的效果,如下所示:

    override func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {
        if collectionView.cellForItem(at: indexPath)?.isSelected ?? false {
            collectionView.deselectItem(at: indexPath, animated: true)
            return false
        }
        return true
    }
    

    @Manav 建议的替代方法是:

    override func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {
        if collectionView.indexPathsForSelectedItems?.contains(indexPath) ?? false {
            collectionView.deselectItem(at: indexPath, animated: true)
            return false
        }
        return true
    }
    

    【讨论】:

    • 谢谢。这是另一种情况,如果不想向集合视图询问单元格:collectionView.indexPathsForSelectedItems?.contains(indexPath) == true
    【解决方案3】:

    我个人认为更简洁的另一个选项是允许在集合视图上进行多项选择,然后在下一次选择之前手动取消选择当前选择的项目。

    第一步:允许多选

    override func viewDidLoad() {
        super.viewDidLoad()
        collectionView.allowsMultipleSelection = true
    }
    

    第二步:手动取消选择之前选择的项目

    func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {
        collectionView.indexPathsForSelectedItems?.forEach { ip in
            collectionView.deselectItem(at: ip, animated: true)
        }
        return true
    }
    

    【讨论】:

      【解决方案4】:

      如果您不想多选,请尝试使用此代码进行取消选择。

      var selectedIndex:Int?
      
      func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
          let cell = collectionView.cellForItem(at: indexPath) as! CategoryCollectionViewCell
          if selectedIndex == indexPath.row {
              selectedIndex = nil
              // unselect code here
          } else {
              selectedIndex = indexPath.row
              // Select code here
          }
      }
      
      func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
          // unselect code here
      }
      

      【讨论】:

        【解决方案5】:

        发布类似的解决方案,但调用委托,以便您保持一切同步,模拟实际取消选择(加上稍微清晰的命名):

        func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {
            let isSelectedAlready = collectionView.indexPathsForSelectedItems?.contains(indexPath)
            if isSelectedAlready == true {
                collectionView.deselectItem(at: indexPath, animated: true)
                collectionView.delegate?.collectionView?(collectionView, didDeselectItemAt: indexPath)
                return false
            }
            return true
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-12-10
          • 1970-01-01
          • 1970-01-01
          • 2013-11-22
          • 1970-01-01
          • 1970-01-01
          • 2017-03-04
          • 1970-01-01
          相关资源
          最近更新 更多