8

使用以下设置

....
MyUIMenuItem *someAction  = [[MyUIMenuItem alloc]initWithTitle : @"Something"  action : @selector(menuItemSelected:)];
MyUIMenuItem *someAction2 = [[MyUIMenuItem alloc]initWithTitle : @"Something2" action : @selector(menuItemSelected:)];
....

- (IBAction) menuItemSelected : (id) sender
{
    UIMenuController *mmi = (UIMenuController*) sender;
}

如何确定选择了哪个菜单项。

并且不要说你需要有两种方法......在此先感谢。

4

4 回答 4

16

好的,我已经解决了这个问题。解决方案并不漂亮,更好的选择是“Apple 解决了问题”,但这至少有效。

首先,在你的UIMenuItem动作选择器前加上“ magic_ ”。并且不要做出相应的方法。(如果你能做到这一点,那么你无论如何都不需要这个解决方案)。

我正在构建我的UIMenuItems

NSArray *buttons = [NSArray arrayWithObjects:@"some", @"random", @"stuff", nil];
NSMutableArray *menuItems = [NSMutableArray array];
for (NSString *buttonText in buttons) {
    NSString *sel = [NSString stringWithFormat:@"magic_%@", buttonText];
    [menuItems addObject:[[UIMenuItem alloc] 
                         initWithTitle:buttonText
                         action:NSSelectorFromString(sel)]];
}
[UIMenuController sharedMenuController].menuItems = menuItems;

现在,您的捕获按钮点击消息的类需要添加一些内容。(在我的例子中,这个类是UITextField的一个子类。你的可能是别的东西。)

首先,我们一直想要但不存在的方法:

- (void)tappedMenuItem:(NSString *)buttonText {
    NSLog(@"They tapped '%@'", buttonText);
}

然后是使之成为可能的方法:

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
    NSString *sel = NSStringFromSelector(action);
    NSRange match = [sel rangeOfString:@"magic_"];
    if (match.location == 0) {
        return YES;
    }
    return NO;
}

- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel {
    if ([super methodSignatureForSelector:sel]) {
        return [super methodSignatureForSelector:sel];
    }
    return [super methodSignatureForSelector:@selector(tappedMenuItem:)];
}

- (void)forwardInvocation:(NSInvocation *)invocation {
    NSString *sel = NSStringFromSelector([invocation selector]);
    NSRange match = [sel rangeOfString:@"magic_"];
    if (match.location == 0) {
        [self tappedMenuItem:[sel substringFromIndex:6]];
    } else {
        [super forwardInvocation:invocation];
    }
}
于 2012-03-26T14:32:21.993 回答
1

人们会期望与给定菜单项相关联的动作将包括一个sender应该指向所选菜单项的参数。然后您可以简单地检查项目的标题,或者按照 kforkarim 的建议进行操作并将 UIMenuItem 子类化以包含可用于识别项目的属性。不幸的是,根据这个 SO question, sender 参数始终为零。这个问题已经有一年多了,所以事情可能已经改变了——看看你在那个参数中得到了什么。

或者,您似乎需要对每个菜单项执行不同的操作。当然,您可以将其设置为使您的所有操作都调用一个通用方法,并且如果它们都执行非常相似的操作,这可能是有意义的。

于 2012-02-05T04:04:32.150 回答
0

事实证明,如果您继承 UIApplication 并重新实现,则可以获得代表 UIMenuItem 的 UIButton 对象(实际上是 UICalloutBarButton)-sendAction:to:from:forEvent:。虽然只有-flash选择器通过 UIApplication,但已经足够了。

@interface MyApplication : UIApplication
@end

@implementation MyApplication
- (BOOL)sendAction:(SEL)action to:(id)target from:(id)sender forEvent:(UIEvent *)event
{
    // target == sender condition is just an additional one
    if (action == @selector(flash) && target == sender && [target isKindOfClass:NSClassFromString(@"UICalloutBarButton")]) {
        NSLog(@"pressed menu item title: %@", [(UIButton *)target titleLabel].text);
    }
    return [super sendAction:action to:target from:sender forEvent:event];
}
@end

您可以将target(或您需要的任何数据)保存在例如属性中,并稍后从您的 UIMenuItem 的操作中访问它。

为了使您的 UIApplication 子类工作,您必须将其名称作为第三个参数传递给UIApplicationMain()

int main(int argc, char *argv[])
{
    @autoreleasepool {
        return UIApplicationMain(argc, argv, NSStringFromClass([MyApplication class]), NSStringFromClass([YOUR_APP_DELEGATE class]));
    }
}

截至发布日期,此解决方案适用于 iOS 5.x-7.0(未在旧版本上测试)。

于 2013-09-17T20:13:55.747 回答
-1

ort11,您可能想要创建 myuimenuitem 的属性并设置某种标记。这样,发件人的对象可以通过其标签来识别。然后在 Ibaction 中,您可以设置一个 switch 语句,该语句可以对应于每个 sender.tag 并通过该逻辑工作。我想这是最简单的方法。

于 2012-02-05T03:51:49.373 回答