swift 显示不带UIButton或UINavigationButton的UIMenu

fnatzsnv  于 2023-05-27  发布在  Swift
关注(0)|答案(2)|浏览(130)

用户。我有一个问题,我似乎不能弄清楚。我想在UICollectionView中按下一行时显示一个UIMenu,所以我添加了一个UIButton,它在每个单元格中边到边扩展。按下按钮时,将出现一个UIMenu。问题是UICollectionView在每个单元格中都有UIButton的情况下是不可滚动的。系统优先考虑UIButton而不是滚动。我希望只有一个UILabel和一个菜单,显示何时调用“didSelectItemAt indexPath”,但UIMenus只能使用UIButton和UINavigationBarButton。
如果有人有办法,请帮帮我!非常感谢,亲切的问候😊

kyks70gy

kyks70gy1#

我怀疑我可能是错的,你已经为UICollectionView设置了delaysContentTouches为false。
这将使任何触摸被解释为按钮敲击。
而不是从单元格中删除按钮,这是我的设置,听起来与您的相似,并给出了所需的最终结果:
自定义UICollectionView,带有标签和按钮,跨越整个集合视图单元格

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
            },
        ])
    }
}

在ViewController中

class UICollectionViewButtonCellViewController: UIViewController
{
    private var collectionView: UICollectionView!
    
    override func viewDidLoad()
    {
        super.viewDidLoad()
        
        title = "Button Cell Example"
        
        view.backgroundColor = .white
        
        configureCollectionView()
    }
    
    private func configureCollectionView()
    {
        collectionView = UICollectionView(frame: CGRect.zero, collectionViewLayout: createLayout())
        
        collectionView.register(ButtonCollectionViewCell.self,
                                forCellWithReuseIdentifier: ButtonCollectionViewCell.reuseIdentifier)
        
        collectionView.dataSource = self
        
        // do not have the below line of code, by default delaysContentTouches is true
        // collectionView.delaysContentTouches = false
        
        view.addSubview(collectionView)
        
        // Auto layout config to pin collection view to the edges of the view
        collectionView.translatesAutoresizingMaskIntoConstraints = false
        collectionView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor).isActive = true
        collectionView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
        collectionView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor).isActive = true
        collectionView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true
    }
    
    private func createLayout() -> UICollectionViewFlowLayout
    {
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .vertical
        
        let availableWidth = view.frame.width
        let interItemSpacing: CGFloat = 5
        
        // (available width - inter item spacing) / 2
        let itemWidth = (availableWidth - interItemSpacing) / 2
        layout.itemSize = CGSize(width: itemWidth, height: 100)
        layout.minimumInteritemSpacing = interItemSpacing
        layout.minimumLineSpacing = 5
        
        return layout
    }
}

extension UICollectionViewButtonCellViewController: UICollectionViewDataSource
{
    func collectionView(_ collectionView: UICollectionView,
                        numberOfItemsInSection section: Int) -> Int
    {
        return 20
    }
    
    func collectionView(_ collectionView: UICollectionView,
                        cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
    {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: ButtonCollectionViewCell.reuseIdentifier,
                                                      for: indexPath) as! ButtonCollectionViewCell
        
        cell.titleLabel.text = "Tap cell \(indexPath.item)"
        
        return cell
    }
}

这给了我一个可滚动的UICollectionView的期望输出,它的水龙头导致UIMenu交互。

8oomwypt

8oomwypt2#

步骤1.

public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = longcollection.dequeueReusableCell(withReuseIdentifier: "longcell", for: indexPath) as! longcell
        let interaction = UIContextMenuInteraction(delegate: self)
        cell.contentView.tag = indexPath.item
        cell.contentView.superview?.tag = indexPath.section
        cell.contentView.addInteraction(interaction)
        return cell
    }

步骤2.

// MARk: - Context Menu & Action Sheet

extension ViewController: UIContextMenuInteractionDelegate {

    public func contextMenuInteraction(_ interaction: UIContextMenuInteraction, configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? {
        return UIContextMenuConfiguration(identifier: "anyIdentifier" as NSCopying, previewProvider: nil, actionProvider: { _ in
            let contextMenu = self.getContextMenu(data: "Copy this data")
            return UIMenu(title: "", children: [contextMenu])
        })
    }

    func getContextMenu(data: String) -> UIMenu {
        let systemIcon = UIImage(systemName: "square.and.arrow.up.circle.fill")
        let customICon = UIImage(named: "bin")

        let copyAction = UIAction(title: "Copy", image: systemIcon) { _ in
            UIPasteboard.general.string = data
        }

        let editImageAction = UIAction(title: "Edit", image: customICon) { _ in
            // Edit message
        }

        let infoAction = UIAction(title: "Info", image: customICon, attributes: .destructive) { _ in
            // write info code here.
        }

        let replyAction = UIAction(title: "Reply", image: systemIcon, attributes: .hidden) { _ in
            // Write reply code here.
        }

        let deleteAction = UIAction(title: "Delete", image: systemIcon, attributes: .disabled) { _ in
            // Delete message goes here
        }

        return UIMenu(title: "", options: .displayInline, children: [copyAction, editImageAction, infoAction, replyAction, deleteAction])
    }

}

您可以按照此Github repo更好地理解。

相关问题