I want to present a menu from a UIBarButtonItem, but only if a runtime check succeeds when the button is tapped, otherwise show an alert.
Quick background. I had some older code (pre-UIMenu days) that handled the UIBarButtonItem with a target/action that would perform the check and then either show an alert or present an action sheet.
I'm trying to update that code to use a UIMenu instead of an action sheet (UIAlertController). I know how to create the UIBarButtonItem with a UIMenu. That's easy to implement.
What I can't find in any APIs or in any searching here on SO, is how to manually display a UIMenu.
Here's a rough example of my code that directly shows a menu from the UIBarButtonItem:
btnAdd = UIBarButtonItem(systemItem: .add, menu: UIMenu(children: [
// An array of UIAction instances for each menu item
]))
That code works just fine but I need to change it so the menu only appears under the right condition. I'm thinking of something like the following but I don't know how to write the line of code that manually displays a UIMenu.
btnAdd = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(addAction))
...
@objc func addAction(_ sender: UIBarButtonItem) {
if someRuntimeCondition == true {
let menu = UIMenu(children: [
// An array of UIAction instances for each menu item
])
??? // How to display menu from sender?
} else {
// Create and display an alert
}
}
I feel like I'm missing something simple and obvious but I just don't see it.
I've reviewed the documentation for UIMenu, UIBarButtonItem, UIContextMenuInteraction, and UIMenuController (deprecated). None of these seem to provide a way to manually display a menu from a UIBarButtonItem. I've also looked at a couple of Apple's sample apps.
Any solution needs to work with iOS 15.0+.
I was seconds away from clicking Submit on my question when I found a tricky solution using
UIDeferredMenuElement.uncached. This doesn't answer the question of how to manually display aUIMenufrom aUIBarButtonItembut this does achieve my ultimate goal of conditionally showing either an alert or a menu when theUIBarButtonItemis tapped.