Is there a way to determine when a UIMenuController has been dismissed? I have a (non-editable) text area I'm highlighting when the menu is brought up, and I'd like to un-highlight it when they either select an item (easy) or cancel (not possible?)
On state changes UIMenuController posts notifications to the default NSNotification center. You can subscribe to them to get notified when the system hides the menu:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willHideEditMenu:) name:UIMenuControllerWillHideMenuNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didHideEditMenu:) name:UIMenuControllerDidHideMenuNotification object:nil];
Building on @Markus Müller's suggestion, here's a pattern you can copy:
- (BOOL)becomeFirstResponder
{
// starts listening for UIMenuControllerDidHideMenuNotification & triggers resignFirstResponder if received
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resignFirstResponder) name:UIMenuControllerDidHideMenuNotification object:nil];
return [super becomeFirstResponder];
}
- (BOOL)resignFirstResponder
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIMenuControllerDidHideMenuNotification object:nil];
// your custom cleanup code here (e.g. deselection)
return [super resignFirstResponder];
}
In my case I have hundreds of selectable objects, so I didn't want them all observing this notification all the time! What this pattern does start observing when it gains firstResponder, triggers resignFirstResponder
when the menu is dismissed, and ends observing in the same.
In my my case (as in the OP's), as the item is uneditable it is desirable for me to call resignFirstResponder
when the menu is dismissed. This way, resignFirstResponder
gets called if whether they select one of the menu options, or not, so the cleanup code will always fire.
Swift 3 & 4
NotificationCenter.default.addObserver(
self,
selector: #selector(self.didHideEditMenu),
name: NSNotification.Name.UIMenuControllerDidHideMenu,
object: nil)
NotificationCenter.default.addObserver(
self,
selector: #selector(self.willHideEditMenu),
name: NSNotification.Name.UIMenuControllerWillHideMenu,
object: nil)
Swift 5
NotificationCenter.default.addObserver(
self,
selector: #selector(willHideMenu),
name: UIMenuController.willHideMenuNotification,
object: nil)
© 2022 - 2024 — McMap. All rights reserved.