Uwe Gropengießer
Uwe Gropengießer

Reputation: 116

UIMenuController in iOS7

I'm actually a little bit confused about the changes in iOS7 for displaying a customized context menu on a UITableView.

My code is the following:

- (void)viewDidLoad {
   UIMenuItem *deleteAction = [[UIMenuItem alloc]initWithTitle:NSLocalizedString(@"Delete", nil) action:@selector(delete:)];
   UIMenuItem *renameAction = [[UIMenuItem alloc]initWithTitle:NSLocalizedString(@"Rename", nil) action:@selector(rename:)];
   UIMenuController* mc = [UIMenuController sharedMenuController];
   mc.menuItems = [NSArray arrayWithObjects: renameAction, deleteAction, nil];
   [mc setTargetRect:CGRectMake(50.0, 50.0, 0, 0) inView:self.view];
   [mc setMenuVisible:YES animated:YES];
   [mc setMenuItems:@[deleteAction, renameAction]];
   [self becomeFirstResponder];

-(void)tableView:(UITableView*)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath*)indexPath withSender:(id)sender{
}

-(BOOL)tableView:(UITableView*)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath*)indexPath withSender:(id)sender {
if (tableView != nil && indexPath != nil)
{
    if (action == @selector(delete:)) {
            return YES;
        }
        if (action == @selector(rename:)) {
            return YES;
        }
    }
    return NO;
}

-(BOOL)tableView:(UITableView*)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath*)indexPath {
    return YES;
}

My problem is, in previews version of iOS everything works fine. The customized context menu appears if a user long pressed a cell of the tableview, but in iOS7 nothing happens. The methods get called but nothing is shown.

Upvotes: 4

Views: 1520

Answers (1)

Ed Chin
Ed Chin

Reputation: 1214

There's a small gotcha with UIMenuController that people always miss.

For the menu to appear, the target view must be in the responder chain. Many UIKit views can't become a responder by default, so you need to subclass them to return YES for canBecomeFirstResponder.

-(BOOL)canBecomeFirstResponder {
    return YES;
}

- (void)menuDelete:(id)sender {
    NSLog(@"delete");
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    NSLog(@"touchesBegan");

    [self becomeFirstResponder];
    UIMenuItem *menuItem = [[UIMenuItem alloc] initWithTitle:@"Delete" action:@selector(menuDelete:)];
    UIMenuController *menuCont = [UIMenuController sharedMenuController];
    [menuCont setTargetRect:self.frame inView:self.superview];
    menuCont.menuItems = [NSArray arrayWithObject:menuItem];
    [menuCont setMenuVisible:YES animated:YES];
}

I hope this helps. I'm happy to help troubleshoot more, so please feel free to give an update if my advice still doesn't fix the problem.

Upvotes: 5

Related Questions