UICollectionView shouldShowMenuForItemAt 未调用

Posted

技术标签:

【中文标题】UICollectionView shouldShowMenuForItemAt 未调用【英文标题】:UICollectionView shouldShowMenuForItemAt Not Called 【发布时间】:2018-08-15 08:18:52 【问题描述】:

我在UIViewController 中有一个股票标准UICollectionView,它是它的代表。然而,shouldShowMenuForItemAt 函数不需要长按。我添加了一个didSelectItemAt 函数,它在单击单元格时会被调用,以确保代理确实正确连接。

我还实现了 canPerformAction 以在委托中返回 true 和 performAction 以及 canPerformActioncanBecomeFirstResponder 在我的 UICollectionViewCell 子类中返回 true。长按单元格时不会调用这些函数。有什么建议吗?

【问题讨论】:

试试这个答案的解决方案:***.com/a/39956745/6126595 @BartoszKunat 我会试一试,但它似乎是一种反模式。从文档来看,这个方法应该由集合视图调用,而不需要这个 hack。 在我的机器上,菜单处理“正常”。无需任何黑客攻击。您可能正在做一些干扰长按手势识别器的操作。 @matt 这也是我的期望。我创建了一个示例项目,其中只有一个来自 IB 的集合视图,并且上面提到的 func 已连接起来,显示了这个问题。 那么您的示例项目成功了吗?如果没有,看看一个有效的例子对你有帮助吗? 【参考方案1】:

大部分人似乎都忽略了这个难题的缺失部分,即为了让菜单工作(在集合视图或表格视图中),单元格必须实现选择器。

这是一个最小的例子。说明:使用 Single View App 模板创建一个新项目。复制这段代码并将其粘贴到 ViewController.swift 中,以便完全替换该文件中的所有内容。跑。长按绿色方块。享受。 (菜单项什么都不做;关键是,您会看到菜单项出现。)

import UIKit
class Cell : UICollectionViewCell 
    @objc func f(_ : Any) 

class ViewController: UIViewController 
    let cellid = "cellid"
    @nonobjc private let howdy = #selector(Cell.f)
    override func viewDidLoad() 
        super.viewDidLoad()
        let cv = UICollectionView(frame: self.view.bounds, collectionViewLayout: UICollectionViewFlowLayout())
        self.view.addSubview(cv)
        cv.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        cv.delegate = self
        cv.dataSource = self
        cv.register(Cell.self, forCellWithReuseIdentifier: cellid)
    

extension ViewController : UICollectionViewDataSource, UICollectionViewDelegate 
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
        return 100
    
    func collectionView(_ cv: UICollectionView, cellForItemAt ip: IndexPath) -> UICollectionViewCell 
        let cell = cv.dequeueReusableCell(withReuseIdentifier: cellid, for: ip)
        cell.backgroundColor = .green
        return cell
    
    func collectionView(_ collectionView: UICollectionView, shouldShowMenuForItemAt indexPath: IndexPath) -> Bool 
        let mi = UIMenuItem(title:"Howdy", action:howdy)
        UIMenuController.shared.menuItems = [mi]
        return true
    

    func collectionView(_ collectionView: UICollectionView, canPerformAction action: Selector, forItemAt indexPath: IndexPath, withSender sender: Any?) -> Bool 
        return (action == howdy)
    
    func collectionView(_ collectionView: UICollectionView, performAction action: Selector, forItemAt indexPath: IndexPath, withSender sender: Any?) 
    

【讨论】:

非常感谢@matt。除了您提到的实现选择器的单元格之外,我还错误地覆盖了视图控制器中的canPerformAction,而不是在UICollectionViewDelegate 中实现了那个! 哦,不错! 有趣的是,UICollectionViewDelegate 中的 performAction 函数不会用于自定义菜单项操作。而是直接调用这些菜单项中的选择器。在集合视图上执行任务相当不方便,例如在我的情况下删除单元格。 我所做的是将它转发给代表。单元中的实现只是一个蹦床。

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

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

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

UICollectionView 断言失败 -[UICollectionView _updateWithItems:tentativelyForReordering:]

UITableviewCell 中的 UICollectionView。添加约束后,UICollectionView 不显示

将标题添加到 UICollectionView,而不是 UICollectionView 的部分

嵌套垂直 UICollectionView 和动态高度