質問

I have added an custom menu in the - (void)viewDidLoad method of my view controller:

UIMenuItem *menuItem = [[UIMenuItem alloc] initWithTitle:@"Read selected" action:@selector(readSelectedText)];
[UIMenuController sharedMenuController].menuItems = [NSArray arrayWithObject:menuItem];

In the same controller I also implement the method:

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
    if (action == @selector(readSelectedText)) {
        if (textView.selectedRange.length > 0) {
            return YES;
        }
        return NO;
    }
    return [super canPerformAction:action withSender:sender];
}

The first time I select some text the menu contains the "Read selected" menu item and it all works well. However in subsequent text selections the menu only contains the standard system menu items like copy. paste, etc. I have checked in the - (BOOL)canPerformAction:(SEL)action withSender:(id)sender method and it never gets called with a readSelectedText action (as it does the first time).

Any idea why this happens?

役に立ちましたか?

解決

I have tried below code,It works to me.The point is before menu shows,add custom menu item, and then show the menu yourself.

-(void)viewDidLoad { [super viewDidLoad];

 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(menuWillShow) name:UIMenuControllerWillShowMenuNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(menuDidShow) name:UIMenuControllerDidShowMenuNotification object:nil];

}

-(void)menuDidShow{

 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(menuWillShow) name:UIMenuControllerWillShowMenuNotification object:nil];

}

-(void)menuWillShow{

UIMenuItem *shareMenu = [[UIMenuItem alloc] initWithTitle:@"微博分享" action:@selector(shareToWeibo:)];
UIMenuController *menu = [UIMenuController sharedMenuController];
[menu setMenuItems:[NSArray arrayWithObjects:shareMenu, nil]];

[[NSNotificationCenter defaultCenter] removeObserver:self name:UIMenuControllerWillShowMenuNotification object:nil];

[menu setTargetRect:selectedRect inView:self.view]; //must set,otherwise menu location never changed

[menu setMenuVisible:YES animated:YES];

}

他のヒント

My solution is based on the suggestion qiufangzhou provided so the credits and the accepted answer go to him.

Anyway, I ended up subscribing to the UIMenuControllerWillShowMenuNotification noritication in my viewDidLoad method:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(menuWillShow) name:UIMenuControllerWillShowMenuNotification object:nil];

Then I implemented this method:

-(void)menuWillShow{
    UIMenuItem *menuItem = [[UIMenuItem alloc] initWithTitle:@"Read selected" action:@selector(readSelectedText)];
    [UIMenuController sharedMenuController].menuItems = [NSArray arrayWithObject:menuItem];
}

The trick is that you have to add the custom menu item every time the menu is shoved, not only once. I guess the custom menu items list gets cleared every time.

For who might still need this:

We need to observe UIMenuControllerDidHideMenuNotification nothing else.

viewDidApear:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(menuDidHide) name:UIMenuControllerWillShowMenuNotification object:nil];

viewDidDisapear:

[[NSNotificationCenter defaultCenter] removeObserver:self name:UIMenuControllerDidHideMenuNotification object:nil];

menuDidHide

UIMenuItem *menuItem = [[UIMenuItem alloc] initWithTitle:@"Read selected" action:@selector(readSelectedText)];
[UIMenuController sharedMenuController].menuItems = [NSArray arrayWithObject:menuItem];
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top