4

How to show UIMenuController under UIBarButtonItem when click it?

Marek Grzenkowicz
  • 17,024
  • 9
  • 81
  • 111
Ali
  • 1,975
  • 5
  • 36
  • 55

1 Answers1

12

Assume your UIBarButtonItem has been connected to:

-(void)buttonClicked:(UIBarButtonItem*)sender event:(UIEvent*)event;

Then paste these codes into your view controller:

-(void)buttonClicked:(UIBarButtonItem*)sender event:(UIEvent*)event{
    [self becomeFirstResponder];

    /*get the view from the UIBarButtonItem*/
    UIView *buttonView=[[event.allTouches anyObject] view];
    CGRect buttonFrame=[buttonView convertRect:buttonView.frame toView:self.view];

    UIMenuController *menuController = [UIMenuController sharedMenuController];
    UIMenuItem *resetMenuItem = [[UIMenuItem alloc] initWithTitle:@"Menu Item" action:@selector(menuItemClicked:)];

    NSAssert([self becomeFirstResponder], @"Sorry, UIMenuController will not work with %@ since it cannot become first responder", self);
    [menuController setMenuItems:[NSArray arrayWithObject:resetMenuItem]];
    [menuController setTargetRect:buttonFrame inView:self.view];
    [menuController setMenuVisible:YES animated:YES];

    [resetMenuItem release];
}
- (void) copy:(id) sender {
    // called when copy clicked in menu
}
- (void) menuItemClicked:(id) sender {
    // called when Item clicked in menu
}
- (BOOL) canPerformAction:(SEL)selector withSender:(id) sender {
    if (selector == @selector(menuItemClicked:) /*|| selector == @selector(copy:)*/ /*<--enable that if you want the copy item */) {
        return YES;
    }
    return NO;
}
- (BOOL) canBecomeFirstResponder {
    return YES;
}

The key is to return YES for canBecomeFirstResponder and canPerformAction.

Here's the sample project if you need it.

These codes are actually come from other posts in stackoverflow, I just combined them.

Figure out UIBarButtonItem frame in window?

How to get UIMenuController work for a custom view?

Community
  • 1
  • 1
b123400
  • 6,138
  • 4
  • 27
  • 27
  • 1
    I found the positioning of the menu was sometimes too far to the right when trying this myself. I was able to fix it by changing the lines: `CGRect buttonFrame=[buttonView convertRect:buttonView.frame toView:self.view];` and `[menuController setTargetRect:buttonFrame inView:self.view];` to: `[menuController setTargetRect:buttonView.frame inView:buttonView.superview];` gave more accurate positions. – Pat Wallace Dec 21 '12 at 22:02