Foundation iOS Swift UIKit

Displaying menus with UIContextMenuInteraction on iOS

iOS 13 added a new class named UIContextMenuInteraction what is used for attaching menus to views. When adding menu interaction to a view and user uses 3D Touch or long press gesture on devices not supporting it, a menu is presented alongside with the highlighted content view. Therefore depending on the available space, not all the menu items can fit into the menu.

Setting up UIContextMenuInteraction

UIContextMenuInteraction is initialised with a delegate. Delegate’s job is to create an instance of UIContextMenuConfiguration with provider block for creating a menu when needed. It also should be noted that delegate can return nil in what case no menu is shown.

let interaction = UIContextMenuInteraction(delegate: self)
imageView.isUserInteractionEnabled = true

Creating UIMenus and UIActions

Action provider of UIContextMenuConfiguration is a function taking in suggested menu items and returning an instance of UIMenu. Suggested menu items are the ones provided by responders from responder chain. For example we could use it for sharing actions among multiple responders.

Every menu item is represented by UIAction or another UIMenu allowing to have nested menus. UIActions have title and optionally image and state icon if the state is on. In addition we can explicitly disable actions and set a destructive appearance.

extension ViewController: UIContextMenuInteractionDelegate {
func contextMenuInteraction(_ interaction: UIContextMenuInteraction, configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? {
let actionProvider: ([UIMenuElement]) -> UIMenu? = { _ in // menu elements from responder chain if any
// Creating actions…
let imageAction = UIAction(title: "Title (image)",
image: UIImage(systemName: "arkit"),
identifier: nil,
discoverabilityTitle: nil,
attributes: [],
state: .off,
handler: actionHandler)
let destructiveAction = UIAction(title: "Title (destructive)",
image: nil,
identifier: nil,
discoverabilityTitle: nil,
attributes: .destructive,
state: .off,
handler: actionHandler)
let submenu = UIMenu(title: "Submenu",
image: nil,
identifier: nil,
options: [],
children: [destructiveAction, disabledAction])
return UIMenu(title: "Optional Menu Title",
image: nil,
identifier: nil,
options: [],
children: [titleAction, imageAction, onDiscoverabilityTitleAction, submenu])
return UIContextMenuConfiguration(identifier: "my identifier" as NSCopying,
previewProvider: nil,
actionProvider: actionProvider)


Creating menus using UIContextMenuInteraction are easy to setup and they look like familiar NSMenu when building iOS app for macOS.

If this was helpful, please let me know on Twitter @toomasvahter. Feel free to subscribe to RSS feed. Thank you for reading.


UIContextMenu (Xcode 11 beta 4)

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s