How to show UIMenu from UIButton or UIBarButtonItem
Learn how to display context / popup menu from UIBarButtonItem and UIButton with this guide.
Published: Feb. 15, 2021 Sponsored I want a Press KitUIMenu
is great new way to provide user with on-demand inline options. Since iOS 13 we could show these menus from TableView and CollectionView cells by implementing one delegate method.
With iOS 14 these menus are getting ever more useful with the option of showing them from UIBarButtons and UIButtons. The UIBarButton
use-case is a bit easier, so start with that.
Example UIMenu
Let's start with example menu definition:
var menuItems: [UIAction] {
return [
UIAction(title: "Standard item", image: UIImage(systemName: "sun.max"), handler: { (_) in
}),
UIAction(title: "Disabled item", image: UIImage(systemName: "moon"), attributes: .disabled, handler: { (_) in
}),
UIAction(title: "Delete..", image: UIImage(systemName: "trash"), attributes: .destructive, handler: { (_) in
})
]
}
var demoMenu: UIMenu {
return UIMenu(title: "My menu", image: nil, identifier: nil, options: [], children: menuItems)
}
Because this is an example, I left the handlers empty.
UIBarButtonItem with UIMenu
Next we can move to the UIBarButtonItem
definition:
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Menu", image: nil, primaryAction: nil, menu: demoMenu)
Since we haven't specified the primaryAction
, the menu will appear immediately after tap.
UIButton + UIMenu
With buttons it is a little bit more complicated. If you want your UIMenu
to appear immediately, you need to set the showsMenuAsPrimaryAction
to true
, otherwise the menu will appear after long press.
@IBOutlet var showMenuButton: UIButton!
func configureButtonMenu() {
showMenuButton.menu = demoMenu
showMenuButton.showsMenuAsPrimaryAction = true
}
With this setup code, after you tap the button, the menu will be automatically presented. Note that there is currently no init
variant for UIButton
that let's you specify pass the menu as a parameter.
I found that this works very well as a replacement where you would traditionally use UIAlertController
in the .actionSheet
configuration. You don’t have to worry about which UIViewController
is going to present the menu and there is no need to set the popover anchor when on iPad. That is a big win.
Uses: Xcode 12 & Swift 5.3