Swift 中未调用 UICollectionView DidDeselectItemAtIndexPath 方法

Posted

技术标签:

【中文标题】Swift 中未调用 UICollectionView DidDeselectItemAtIndexPath 方法【英文标题】:UICollectionView DidDeselectItemAtIndexPath method not called in Swift 【发布时间】:2017-08-04 23:55:18 【问题描述】:

我有一个收藏视图,其中列出了一堆视频,点击其中任何一个都会推送包含自定义播放器视图的导航控制器来播放视频。点击客户播放器视图上的关闭按钮将弹出当前控制器并返回视频列表控制器。

此外,当点击其中一个单元格时,该单元格将变为灰色。当返回并从视频列表中点击另一个单元格时,我想取消选择之前选择的单元格并将其恢复为白色并将新选择的单元格变为灰色。

问题是,didDeselectCellAtIndexPath 方法永远不会被调用。先前选择的单元格确实被取消选择,我可以从所选 indexPath 的打印中看到。然而,委托方法永远不会被调用,因此 backgroundColor 永远不会变回白色。尽管 allowMultipleSesection 已设置为 false,但似乎选择了多个单元格。

设置如下配置:

let layout = UICollectionViewFlowLayout()
collectionView?.collectionViewLayout = layout
collectionView?.delegate = self
collectionView?.dataSource = self
collectionView?.allowsSelection = true
collectionView?.allowsMultipleSelection = false

这是我的 collectionView 方法和委托方法:

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
    
    let cell =  collectionView.dequeueReusableCell(withReuseIdentifier: cellID, for: indexPath) as! PreviewCell
    cell.snapShotImageView.image = videoInfoArray[indexPath.item].previewImg
    cell.durationLabel.text = videoInfoArray[indexPath.item].lengthText()
    cell.dateLabel.text = videoInfoArray[indexPath.item].dateAddedText()
    return cell



override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) 
    let cell = collectionView.cellForItem(at: indexPath) as! PreviewCell
    cell.backgroundColor = UIColor.rgb(red: 240, green: 240, blue: 240)
    let url = URL(fileURLWithPath: videoInfoArray[indexPath.item].path)
    let vc = VideoController()
    self.videoController = vc
    vc.url = url
    self.navigationController?.pushViewController(vc, animated: true)



override func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) 
    let cell = collectionView.cellForItem(at: indexPath) as! PreviewCell
    
    cell.backgroundColor = UIColor.white
    cell.captionFileLabel.backgroundColor = .white
    print("Deselect called!!! This line should be printed, but it never happens!!!!")

【问题讨论】:

为什么你的委托方法有关键字override?我的意思是,你在继承什么类?如果父类没有实现委托方法,那么任何子类也无法实现。 @zero UICollectionViewController、UICollectionViewDelegateFlowLayout、UIImagePickerControllerDelegate、UINavigationControllerDelegate,我正在继承或采用这些类或协议。当我删除“覆盖”时,它会弹出错误提示我添加“覆盖”。 collectionView 配置下试试这个:clearsSelectionOnViewWillAppear = false @zero Dude 请在下面写一个答案,复制您所做的第一条评论“如果父类没有实现委托方法,任何子类也不会”,我会接受它作为正确答案。是你的暗示救了我的命。是的,我没有采用 UICollectionViewDelegate,它是唯一可以完成这项工作的。谢谢。 【参考方案1】:

如果父类没有实现委托方法,任何子类也无法实现。

请确保您的子类实现它。

【讨论】:

【参考方案2】:

从文档中我可以理解,当用户选择单元格 X,然后选择单元格 Y 时,会调用此方法。现在取消选择单元格 X,将调用该方法。

在移动到新视图控制器之前保存所选单元格的索引,当您返回到集合视图控制器时,以编程方式取消选择单元格,然后在您自己的函数中运行您想要在取消选择委托中运行的内容方法。

当用户尝试取消选择集合视图中的项目时,集合视图会调用此方法。当您以编程方式取消选择项目时,它不会调用此方法。 如果不实现该方法,默认返回值为true。

【讨论】:

【参考方案3】:

didDeselectItemAtallowsMultipleSelection 设置为 true 时被调用。

backgroundColor 永远不会变回白色

即使您之前选择的单元格确实被取消选择,因为您的视图没有得到更新。每次返回时都需要更新集合视图单元格视图。您可以在 collectionViewController 子类的 viewWillAppear 中刷新完整的 UICollectionView。也可以使用@entire 方法取消选择所有选中的indexPath。

【讨论】:

【参考方案4】:

在您的didSelectItemAt 方法结束时,在集合视图上调用deselectItem(at:animated:) 方法。

【讨论】:

【参考方案5】:

让单元格处理其背景颜色。 只需将以下内容添加到您的“PreviewCell”类中:

override var isSelected: Bool 
    didSet 
        // TODO: replace .red & .blue with desired colors
        backgroundColor = isSelected ? .red : .blue
    

【讨论】:

以上是关于Swift 中未调用 UICollectionView DidDeselectItemAtIndexPath 方法的主要内容,如果未能解决你的问题,请参考以下文章

在 Swift4 中未调用 forwardingTarget

从 Objc 超类继承的 Swift 子类中未调用 viewDidLoad

Swift 中未调用 UICollectionView DidDeselectItemAtIndexPath 方法

Swift:在自定义视图中未调用 UIButton 触摸事件

Swift 3 / Xcode 8 beta 6 中未调用 UIApplicationShortcutItem 的 AppDelegate 函数

Swift函数iOS中未返回数据[重复]