16

我在 UINavigationController 内的 UIViewController 中将 UIButton 设置为 rightBarButtonItem,并将 iOS13 上下文菜单关联到它。

长按按钮会按预期显示上下文菜单。

有没有办法通过点击按钮来显示上下文菜单(例如,通过为 .touchUpInside 事件添加目标)?

button/barButtonItem 设置如下:

let button = UIButton(type: .system)
button.setImage(UIImage(systemName: "plus"), for: .normal)

let barButton = UIBarButtonItem(customView: button)
self.navigationItem.rightBarButtonItem = barButton

let interaction = UIContextMenuInteraction(delegate: self)
button.addInteraction(interaction)

上下文菜单定义如下:

extension ViewController: UIContextMenuInteractionDelegate {
    func contextMenuInteraction(_ interaction: UIContextMenuInteraction, configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? {
        return UIContextMenuConfiguration(identifier: nil, previewProvider: nil) { suggestedActions in
            let importAction = UIAction(title: "Import", image: UIImage(systemName: "folder")) { action in }
            let createAction = UIAction(title: "Create", image: UIImage(systemName: "square.and.pencil")) { action in }
            return UIMenu(title: "", children: [importAction, createAction])
        }
    }
}
4

2 回答 2

10

iOS 14

iOS 14(第一个 Beta)现在支持所需的功能。使用以下代码点击UIBarButtonItem将立即显示菜单(同时避免调用 UIContextMenuInteraction 导致的模糊背景):

override func viewDidLoad() {
    super.viewDidLoad()
    
    let importAction = UIAction(title: "Import", image: UIImage(systemName: "folder")) { action in }
    let createAction = UIAction(title: "Create", image: UIImage(systemName: "square.and.pencil")) { action in }
    
    let menuBarButton = UIBarButtonItem(
        title: "Add",
        image: UIImage(systemName:"plus"),
        primaryAction: nil,
        menu: UIMenu(title: "", children: [importAction, createAction])
    )
    
    self.navigationItem.rightBarButtonItem = menuBarButton
}

该功能是通过提供primaryAction.

您可以使用UIButton实现相同的效果。在这种情况下,您需要设置

button.showsMenuAsPrimaryAction = true

UIButton 的完整代码如下所示:

override func viewDidLoad() {
    super.viewDidLoad()
   
    let button = UIButton(type: .system)
    button.setImage(UIImage(systemName: "plus"), for: .normal)
    button.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(button)
    
    NSLayoutConstraint.activate([
        button.centerXAnchor.constraint(equalTo: view.centerXAnchor),
        button.centerYAnchor.constraint(equalTo: view.centerYAnchor)
    ])
    
    let importAction = UIAction(title: "Import", image: UIImage(systemName: "folder")) { action in }
    let createAction = UIAction(title: "Create", image: UIImage(systemName: "square.and.pencil")) { action in }
    
    let items = [importAction, createAction]
    
    button.menu = UIMenu(title: "Add", children: items)
    button.showsMenuAsPrimaryAction = true
}

于 2020-07-13T11:43:18.537 回答
7

根据设计,上下文菜单在适当的手势(强制触摸或长按)发生时由系统自动显示。你不能手动显示它。

来自文档

上下文菜单交互对象跟踪支持 3D Touch 的设备上的Force Touch手势,以及不支持它的设备上的长按手势。

UIKit管理所有与菜单相关的交互并将所选操作(如果有)报告回您的应用程序。

更新

尽管仍然无法在 iOS 14 中手动显示上下文菜单,但现在可以将UIMenu我们为上下文菜单创建的下拉菜单显示。查看@Lobo 的答案以了解如何在 iOS 14 上执行此操作。

于 2019-09-03T16:21:53.833 回答