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;
}

どのメニュー項目が選択されたかを把握する方法。

2 つの方法が必要だとは言わないでください。よろしくお願いします。

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 パラメータは常に nil です。その質問は 1 年以上前のものなので、状況が変わっている可能性があります。そのパラメーターで何が得られるかを見てください。

または、メニュー項目ごとに異なるアクションが必要になるようです。もちろん、すべてのアクションが共通のメソッドを呼び出すように設定することもできます。また、すべてのアクションが非常に類似したことを行う場合、意味があるかもしれません。

于 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 サブクラスを機能させるには、その名前を 3 番目のパラメーターとして に渡す必要があります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 のプロパティを作成し、ある種のタグを設定することができます。このようにして、送信者のオブジェクトはそのタグ it によって認識できます。Ibaction では、各 sender.tag に対応する switch ステートメントを設定し、そのロジックを処理できます。それが一番簡単な方法だと思います。

于 2012-02-05T03:51:49.373 に答える