简体   繁体   English

在collectionView中为单元格手动调用上下文菜单

[英]Manually invoke context menu in collectionView for cell

I implemented methods for context menu with delegate methods like this:我使用如下委托方法实现了上下文菜单的方法:

func collectionView(_ collectionView: UICollectionView, contextMenuConfigurationForItemAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? {
    configureContextMenu(index: indexPath.row)
}

func configureContextMenu(index: Int) -> UIContextMenuConfiguration {
    let context = UIContextMenuConfiguration(identifier: nil, previewProvider: nil) { (action) -> UIMenu? in
        
        let edit = UIAction(title: "Edit", image: UIImage(systemName: "square.and.pencil"), identifier: nil, discoverabilityTitle: nil, state: .off) { (_) in
            print("edit button clicked")
        }
        let delete = UIAction(title: "Delete", image: UIImage(systemName: "trash"), identifier: nil, discoverabilityTitle: nil,attributes: .destructive, state: .off) { (_) in
            print("delete button clicked")
        }
        
        return UIMenu(title: "Options", image: nil, identifier: nil, options: UIMenu.Options.displayInline, children: [edit,delete])
        
    }
    return context
}

It's working fine and as I wanted.它工作正常,如我所愿。 But I am targeting like older audience and I am not sure if they would know that they can hold cells for context menu.但我的目标受众是年长的观众,我不确定他们是否知道他们可以为上下文菜单保存单元格。 So I want to add three dots to right corner and after they tap that it shows same context menu for cell.所以我想在右上角添加三个点,然后在他们点击后显示相同的单元格上下文菜单。 Is is possible to do this?有可能做到这一点吗? How can I manually invoke it?如何手动调用它?

Thanks for help感谢帮助

I believe it is not possible to manually invoke UIContextMenus as their interaction trigger and event management is handled internally as per the docs我相信手动调用 UIContextMenus 是不可能的,因为它们的交互触发器和事件管理是按照文档在内部处理的

A context menu interaction object tracks Force Touch gestures on devices that support 3D Touch, and long-press gestures on devices that don't support it.上下文菜单交互 object 跟踪支持 3D Touch 的设备上的Force Touch手势,以及不支持它的设备上的长按手势。

The only work around I can think of is to use UIMenu with a UIButton on your collection view cell.我能想到的唯一解决方法是在您的集合视图单元格上使用带有 UIButton 的 UIMenu。

I call it a work around rather than a solution because you will gain with the one tap user experience but you will lose the blurry background and focus of the user interaction that UIContextMenu gives you with collection view and table views.我将其称为解决方案而不是解决方案,因为您将获得一键式用户体验,但您将失去 UIContextMenu 为您提供集合视图和表格视图的用户交互的模糊背景和焦点。

Nonetheless, here is my implementation of the custom UICollectionViewCell where the button pins to the edges of the cell, however you can size it as you wish.尽管如此,这是我对自定义 UICollectionViewCell 的实现,其中按钮固定在单元格的边缘,但是您可以根据需要调整其大小。 You can check if this is feasible for your use case:您可以检查这对您的用例是否可行:

class ButtonCollectionViewCell: UICollectionViewCell
{
    static let reuseIdentifier = "ButtonCollectionViewCell"
    
    let titleLabel = UILabel()
    let hiddenButton = UIButton()
    
    override init(frame: CGRect)
    {
        super.init(frame: frame)
        contentView.backgroundColor = .yellow
        configureLabel()
        configureButton()
        layoutIfNeeded()
    }
    
    required init?(coder: NSCoder)
    {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func configureLabel()
    {
        contentView.addSubview(titleLabel)
        
        // Auto layout config to pin label to the edges of the content view
        titleLabel.translatesAutoresizingMaskIntoConstraints = false
        titleLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor).isActive = true
        titleLabel.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
        titleLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor).isActive = true
        titleLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
    }
    
    private func configureButton()
    {
        addSubview(hiddenButton)
        
        // I add this red color so you can see the button takes up the whole cell
        hiddenButton.backgroundColor = UIColor(red: 1.0, green: 0.0, blue: 0.0, alpha: 0.75)
        
        // Auto layout config to pin button to the edges of the content view
        hiddenButton.translatesAutoresizingMaskIntoConstraints = false
        hiddenButton.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
        hiddenButton.topAnchor.constraint(equalTo: topAnchor).isActive = true
        hiddenButton.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
        hiddenButton.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
        
        // Configure menu
        hiddenButton.showsMenuAsPrimaryAction = true
        hiddenButton.menu = UIMenu(title: "Select an option", children: [
            
            UIAction(title: "Option 1") { action in
                // do your work
            },
            
            UIAction(title: "Option 2") { action in
                // do your work
            },
        ])
    }
}

The result is the following on single tap:结果如下:

带有自定义 UICollectionViewCell 的 UICollectionView 以显示从 UIButton 触发的 UIMenu UIContextMenuConfiguration UIContextMenuInteraction 交互

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM