Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIMenuController not showing up

I'm trying to create a custom UIMenuController and display it in my view. Here's my code:

UIMenuController *menuController = [UIMenuController sharedMenuController];
    UIMenuItem *listMenuItem = [[UIMenuItem alloc] initWithTitle:@"List" action:@selector(addList:)];

    [menuController setMenuItems:[NSArray arrayWithObject:listMenuItem]];
    [menuController setTargetRect:CGRectMake(50.0, 50.0, 0, 0) inView:self.view];
    [menuController setMenuVisible:YES animated:YES];

    [listMenuItem release];

There are no errors or exceptions, but the menu controller just doesn't show up.

like image 947
indragie Avatar asked Jun 24 '10 18:06

indragie


3 Answers

You need to do three things:

  1. You need to call -becomeFirstResponder on the view or view controller.
  2. Your view or view controller needs to implement -canBecomeFirstResponder (returning YES).
  3. Optionally, your view or view controller can implement -canPerformAction:action withSender:sender to show/hide menu items on an individual basis.
like image 56
OZ Apps Avatar answered Nov 10 '22 06:11

OZ Apps


The answer mentions three things, but to be picky, there are six:

  1. The menu handler must be a UIView. If it isn't, -becomeFirstResponder fails.
  2. The menu handler must have userInteractionEnabled = YES
  3. The menu handler must be in the view hierarchy and its -window property must be the same as the window for the view in the inView: argument.
  4. You need to implement -canBecomeFirstResponder and return YES.
  5. You need to call [handler becomeFirstResponder], before [menu setTargetRect:inView:] is called, or the latter will fail.
  6. You need to call [menu setTargetRect:inView] (at least once) and [menu setMenuVisible:animated:].

In particular points 1-3 above got me. I wanted a custom menu handler class that was a UIResponder at first, which caused -becomeFirstResponder to return NO; then it was a UIView, which failed, then I tried making it a UIButton which worked, but only because userInteractionEnabled defaults to YES for buttons and NO for UIViews.

like image 25
Kalle Avatar answered Nov 10 '22 06:11

Kalle


UIMenuController is visible on any view only if the view is first responder and

- (BOOL)canPerformAction method returns YES

Hence if your menu controller is to be shown on button click, the first line in the button action should be [self becomeFirstResponder]. NOTE: here self is the view which will present the menus.

If your menus are to be shown on long press gesture, then add longPressGesture to the UIView and in the longpress event before writing

[menuController setTargetRect:CGRectMake(50.0, 50.0, 0, 0) inView:self.view];
[menuController setMenuVisible:YES animated:YES];

write [self becomeFirstResponder];

Then follow the steps mentioned by OZ.

like image 15
Snehal Avatar answered Nov 10 '22 06:11

Snehal