6

I am trying to use UIMenuCnotroller to show a list of dynamically generated items, they share the same action method, and so I need to know which item is selected in the single action method.

However, in the action method - (void)menuItemAction:(id)sender;the sender is actually the UIMenuController object, and I didn't find any method of UIMenuController can tell me which menuitem is selected.

One solution I can think of is to dynamically generate different action selectors for different items, and do some tricks in forwardInvocation

But is there any easier way?

Stefan
  • 14,530
  • 4
  • 55
  • 62
Hao Gong
  • 63
  • 1
  • 3

3 Answers3

2

You can use UIMenuCnotroller like: 1) creation:

UIMenuController *menuController = [UIMenuController sharedMenuController];
        UIMenuItem *open = [[UIMenuItem alloc] initWithTitle:@"Open" action:@selector(open:)];
        UIMenuItem *reDownload = [[UIMenuItem alloc] initWithTitle:@"Re-Download" action:@selector(reDownload:)];

        [menuController setMenuItems:[NSArray arrayWithObjects:open, reDownload, nil]];
        [menuController setTargetRect:cell.frame inView:self.view];
        [menuController setMenuVisible:YES animated:YES];

        [open release];
        [reDownload release];

2) To catch actions should implement next methods:

- (BOOL) canPerformAction:(SEL)selector withSender:(id) sender 
{
    if (selector == @selector(open:))
    {
        return YES;
    }

    if (selector == @selector(reDownload:))
    {
        return YES;
    }

    return NO;
}

- (BOOL) canBecomeFirstResponder 
{
    return YES;
}

3) And realization of yours methods:

- (void) open:(id) sender 
{
    [self doSomething];
}

- (void) reDownload:(id) sender 
{
[self doSomething];
}

Hope, this helps.

Igor
  • 4,235
  • 3
  • 34
  • 32
  • Thanks. This is different from what I need, in my case the two menu items want to shard the same action. For example, put two file names to two menu items, then they will share the same -(void)open:(id)sender – Hao Gong Jan 09 '12 at 04:45
  • Yes, but you can realize the same methods in differents actions methods. In other words, has 2 items and 2 differents actions. In the body of each actons you can define what items has been selected and call share method. – Igor Jan 09 '12 at 08:37
  • Just take opening files as an example, assume that we want to show a menu, each item of which shows a file name in app's document folder, and tap it will load the file. In this case we don't know how many files should be shown until running, so we can't assign different methods to different menu items, unless to use a fake selector and leverage [NSObject forwardInvocation:] – Hao Gong Jan 09 '12 at 23:00
  • Hi krock. I want to intercept when copy, cut or paste from menu items are selected.. Iam using selectors copy: , paste: and cut: in canPerformAction method and it is not working. Any clue.. – Muhammad Irfan Apr 24 '14 at 12:40
1

One easiest way would be to use different @selector method for each menu item

Examples:

UIMenuItem *oneObj = [[UIMenuItem alloc] initWithTitle:@"One" action:@selector(One:)];

UIMenuItem *twoObj = [[UIMenuItem alloc] initWithTitle:@"Two" action:@selector(Two:)];
Durai Amuthan.H
  • 31,670
  • 10
  • 160
  • 241
1

Okay, I've solved this one. It involves messing with [NSObject forwardInvocation:] and is a bit dirty, but the resulting code is quite minimal. Answered over here: https://stackoverflow.com/a/9874092/790036

Community
  • 1
  • 1
sobri
  • 1,626
  • 15
  • 28