UICollectionView didSelectItemAt/didUnselectItemAt 不起作用

Posted

技术标签:

【中文标题】UICollectionView didSelectItemAt/didUnselectItemAt 不起作用【英文标题】:UICollectionView didSelectItemAt/didUnselectItemAt doesn't work 【发布时间】:2016-12-29 15:24:53 【问题描述】:

我有一个UICollectionView,我实现了collectionView(_:didSelectItemAt:)collectionView(_:didDeselectItemAt:)。当我滚动到集合视图的底部并选择它时,我希望它保持选中状态,所以我不会在collectionView(_:didSelectItemAt:) 中调用collectionView(_:didDeselectItemAt:)。现在,问题是当我从底部的选定单元格滚动到顶部的单元格时,应用程序崩溃unexpectedly found nil while unwrapping an Optional value。我的直觉告诉我,这与引擎盖下的细胞出队有关。

override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) 
        let cell = collectionView.cellForItem(at: indexPath) as! ServiceMenuItemCell
        cell.backgroundColor = UIColor(colorLiteralRed: 0/255.0, green: 138/255.0, blue: 217/255.0, alpha: 1.0)

        UIView.animate(withDuration: 0.1, animations: 
            cell.transform = CGAffineTransform(scaleX: 0.9, y: 0.9)
        , completion:  finish in
            UIView.animate(withDuration: 0.05, animations: 
                cell.transform = CGAffineTransform.identity
            )
        )
    

    override func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) 
        let cell = collectionView.cellForItem(at: indexPath) as! ServiceMenuItemCell
        cell.backgroundColor = UIColor(colorLiteralRed: 177/255.0, green: 179/255.0, blue: 181/255.0, alpha: 1.0)
    

我该如何正确解决这个问题?

【问题讨论】:

显示崩溃的代码。你在collectionView(_:didSelectItemAt:) 方法中做了什么? How can I fix crash when tap to select row after scrolling the tableview? 的可能重复项。崩溃的逻辑是一样的。你也可以看到here 我添加了代码,@ArtemNovichkov。亲爱的,感谢您指向我的链接,但我不认为它真的是重复的,因为我认为情况不同。 当您在didDeselectItemAt 中向下滚动并且单元格变为nil 时会出现问题,因为它不再出现在屏幕上......所以它完全一样。解释为什么不是 是的,我知道。我从您放在这里的链接中实现了代码。我用if let cell = dequeue... 解开单元格,它现在选择了两个单元格。 【参考方案1】:

你有两个问题:

didDeSelectItemAt 中的安全展开以避免崩溃 出于您的预期目的:撤消您在DidSelectAtIndexdidDeSelectItemAt 中已经完成的操作

代码

override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) 
            let cell = collectionView.cellForItem(at: indexPath) as! ServiceMenuItemCell
            cell.backgroundColor = UIColor(colorLiteralRed: 0/255.0, green: 138/255.0, blue: 217/255.0, alpha: 1.0)

    UIView.animate(withDuration: 0.1, animations: 
        cell.transform = CGAffineTransform(scaleX: 0.9, y: 0.9)
    , completion:  finish in
        UIView.animate(withDuration: 0.05, animations: 
            cell.transform = CGAffineTransform.identity
        )
    )


override func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) 
    guard let cell = collectionView.cellForItem(at: indexPath) as! ServiceMenuItemCell else return
    cell.backgroundColor = UIColor(colorLiteralRed: 177/255.0, green: 179/255.0, blue: 181/255.0, alpha: 1.0)

另外关于您选择 2 个单元格的问题:

在您的didSelectItemAt 中,您在做什么?你正在改造细胞。因此,在您的 didSelect 中,您必须撤消所做的任何事情。我的意思是你的didDeSelectItemAt 正在工作,但是你对细胞所做的任何突变都必须撤消。 didDeselectItemAt 可帮助您在正确的时间执行此操作。我不确定您的选择是如何工作的,但我认为您更清楚,只需撤消它。

让我知道它是否有效

【讨论】:

以上是关于UICollectionView didSelectItemAt/didUnselectItemAt 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

使用 didSelectRowAtIndexPath 进行转场

Swift UITableView didSelectRowAtIndexPath 错误

折叠UICollectionView

-[UICollectionView _endItemAnimations] 中的 UICollectionView 断言失败

如何滚动另一个 UICollectionView 下方的 UICollectionView?

UICollectionView 单元内部已加载,但 UICollectionView 未显示