Determine when a UIMenuController is dismissed?
Asked Answered
A

4

21

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?)

Ahvenanmaa answered 7/9, 2010 at 3:19 Comment(0)
O
42

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];
Ornstead answered 15/9, 2010 at 12:2 Comment(0)
H
11

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.

Homologous answered 21/3, 2014 at 9:2 Comment(0)
D
3

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)
Dissipation answered 15/2, 2018 at 19:33 Comment(1)
NSNotification.Name.UIMenuControllerWillHideMenu and NSNotification.Name.UIMenuControllerDidHideMenu are changed to UIMenuController.didHideMenuNotification and UIMenuController.willHideMenuNotificationMarylyn
E
1

Swift 5

NotificationCenter.default.addObserver(
        self,
        selector: #selector(willHideMenu),
        name: UIMenuController.willHideMenuNotification,
        object: nil)
Eldred answered 16/10, 2020 at 15:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.