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

Posted

技术标签:

【中文标题】在点击时切换 UICollectionView Cell 的选择/取消选择状态 - Swift【英文标题】:Toggle select / deselect state of a UICollectionView Cell on tap - Swift 【发布时间】:2016-05-14 03:41:22 【问题描述】:

所以首先我已经在这上面停留了几天,花了一整天的时间阅读并尝试了 Stack Overflow 上的许多选项,但对我的成功没有影响

我想要完成的事情听起来很简单,并且翻阅 Apple 文档,在我看来它应该可以工作 https://developer.apple.com/library/ios/documentation/UIKit/Reference/UICollectionViewDelegate_protocol/#//apple_ref/occ/intfm/UICollectionViewDelegate/collectionView:shouldHighlightItemAtIndexPath:

基本上我想要实现的是在点击时切换 UICollectionView Cell 的选定状态。

第一次点击 - 将单元格发送到选定状态并将背景颜色更改为白色。

第二次点击 - 使单元格进入取消选择状态并更改背景颜色以清除

ViewController -

 func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell 
    if let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as? CollectionViewCell 
        cell.cellImage.image = UIImage(named: images[indexPath.row])
        return cell
     else 
        return CollectionViewCell()
    


func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) 
    if let cell = collectionView.cellForItemAtIndexPath(indexPath) as? CollectionViewCell 
        cell.toggleSelectedState()
    


func collectionView(collectionView: UICollectionView, didDeselectItemAtIndexPath indexPath: NSIndexPath) 
    if let cell = collectionView.cellForItemAtIndexPath(indexPath) as? CollectionViewCell 
        cell.toggleSelectedState()
    

单元格 -

    func toggleSelectedState() 
    if selected 
        print("Selected")
        backgroundColor = UIColor.whiteColor()
     else 
        backgroundColor = UIColor.clearColor()
        print("Deselected")
    

我遇到的问题是在点击已选择的单元格时没有调用 didDeselectItemAtIndexPath,但如果我点击另一个单元格,它将被调用并选择新单元格...

我已经尝试检查 shouldSelectItemAtIndexPath 和 shouldDeselectItemAtIndexPath 中的选定状态,我什至尝试编写一个 tapGesture 来解决这个问题,但仍然没有运气......

我有什么遗漏吗? 或者有任何已知的解决方法吗? 任何帮助将不胜感激!

【问题讨论】:

当点击同一个单元格时,它必须再次调用didSelectItemAtIndexPath。请检查 【参考方案1】:

使用 shouldSelectItemAt 并检查集合视图的 indexPathsForSelectedItems 属性以确定是否应该选择或取消选择单元格。

func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool 
    if let indexPaths = collectionView.indexPathsForSelectedItems, indexPaths.contains(indexPath) 
        collectionView.deselectItem(at: indexPath, animated: true)
        return false
    

    return true

【讨论】:

【参考方案2】:

也许您可以创建一个与单元格具有相同边界的 UIButton(),并识别按钮中的选择。然后在按钮的点击动作中,您可以做一些事情来“取消选择”“选中”的单元格。

【讨论】:

啊当然!甚至没有想到...没有像我希望的那样工作,但我使用通知让它工作谢谢!【参考方案3】:

您可以将 UICollectionView 的 allowsMultipleSelection 属性设置为 YES(true),然后集合视图将不会取消选择上一个项目。

【讨论】:

【参考方案4】:

我将这项工作用于一个集合视图,该视图允许通过使用轻击手势识别器来选择和取消选择多个单元格。

单元格:

class ToggleCollectionViewCell: UICollectionViewCell 
    var didChangeSelection: (Bool) -> Void =  _ in 

    required init?(coder: NSCoder) 
        super.init(coder: coder)
        
        let tap = UITapGestureRecognizer(target: self, action: #selector(didTap))
        addGestureRecognizer(tap)
    

    @objc private func didTap() 
        isSelected.toggle()
        didChangeSelection(isSelected)
    

控制器:

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "toggleCell", for: indexPath)

    if let toggleCell = cell as? ToggleCollectionViewCell 
        // do your cell setup...
        lineCell.didChangeSelection =  isSelected in
            guard let self = self else  return 
            // ... handle selection/deselection
        
    

    return cell

【讨论】:

以上是关于在点击时切换 UICollectionView Cell 的选择/取消选择状态 - Swift的主要内容,如果未能解决你的问题,请参考以下文章

UICollectionView contentOffset 错误

单击 UIButton 时切换/更改 UICollectionView 中的单元格

为啥我不能从我的 UICollectionView 中删除图像?

Swift:在切换视图后使用UILongPressGestureRecognizer时应用程序崩溃

在滚动期间点击时,UICollectionView 不再识别单元格上的点击?

点击时将图像设置为 UICollectionView 单元格