Search code examples
swiftdelegatesdismissuimenu

Dismiss delegate for UIMenuElement Swift


I have a UIMenu on my app and I want to detect when a user taps outside(dismiss) the UIMenu. But it seems like Apple does not support any delegates by default for this action. Because when a user taps outside I want to change the image of the button. Sample Image


Solution

  • One rather hacky way I found, is to subclass UIButton and override contextMenuInteractionWillEndFor.

    class MyButton: UIButton {
        override func contextMenuInteraction(_ interaction: UIContextMenuInteraction, willEndFor configuration: UIContextMenuConfiguration, animator: UIContextMenuInteractionAnimating?) {
            super.contextMenuInteraction(interaction, willEndFor: configuration, animator: animator)
            print("ending!")
        }
    }
    

    contextMenuInteractionWillEndFor is the delegate method that is called when you dismiss a UIMenu, but if you are setting the button's menu property, the button itself will become the delegate of the UIContextMenuInteraction, and you can't set it to something else, which is why you have to subclass UIButton.

    Compare this to when you are adding a context menu using addInteraction, where you have control over the UIContextMenuInteractionDelegate.