3
votes

In a UIWebView, I want a certain class div element to display only one custom contextual menu entry. So that I implemented the canPerformAction:: method in the UIWebView delegate like this:

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {

 if (self.webView.superview != nil) {

     BOOL isMyClass=[[self.webView stringByEvaluatingJavaScriptFromString:@"window.getSelection().getRangeAt(0).startContainer.parentNode.className;"] isEqualToString:@"myClass"];
     if (isMyClass) {
         if (action == @selector(myAction:)) {
             return YES;
         } else {
             return NO; // should disable any other menu items
         }
     } 
 }
 return [super canPerformAction:action withSender:sender];
}

The result is quite strange: when the user selects such a myclass div, most menuItems are not displayed (cut: copy: past:...) but select: and selectAll: are still displayed (along with myAction). Under debugger, I notice that these two select/selectAll methods do not fire canPerformAction:: in the delegate... Where are these two method fired?

2
Checkout this answer (by me) for dealing with a similar problem on iOS7: disable-long-press-menu-in-text-area-input-uiwebviewShayan RC

2 Answers

1
votes

I think I know why you may be having problems.

I had the same question and similar frustration:

"Why are select: and selectAll: not appearing when stepping through calls to canPerformAction::?"

I then realized that the firstResponder when displaying the UIMenuController was just a container, and that this class had a member that was actually extending the UITextView class. Since the sharedMenuController interacts with the first responder in the Responder chain, implementing canPerformAction in the container skipped select and selectAll because they had already been handled by the textView member (the REAL firstResponder in this situation).

What you should do is find which object is your firstResponder when displaying the UIMenuController, find any responder objects it might own until you find the highest responder on the stack, and implement canPerformAction there.

Good Luck!

0
votes

Sometimes, when application is used on the iPad device, with no connection to Xcode, the menu correctly displays only the authorized item... Sometimes not... Very erratic behaviour indeed