Disable long press menu in text area/input UIWebview

后端 未结 2 1223
别那么骄傲
别那么骄傲 2021-01-20 00:12

This seems to be one of the most frequently discussed topics here but I couldn\'t find a solution which actually works. I\'m posting this question to share a solution which

2条回答
  •  离开以前
    2021-01-20 00:48

    The root cause of the first solution not working is the subview called UIWebBrowserView. This seems to be the view whose canPerformAction returns true for any action displayed in the context menu.

    Since this UIWebBrowserView is a private class we shouldn't try to subclass it (because it will get your app rejected).

    So what we do instead is we make another method called mightPerformAction:withSender:, like so-

    - (BOOL)mightPerformAction:(SEL)action withSender:(id)sender {
    
    
    NSLog(@"******Action!! %@******",NSStringFromSelector(action));
    
    
      if (action == @selector(copy:))
      {
          NSLog(@"Copy Selector");
          return NO;
      }
      else if (action == @selector(cut:))
      {
          NSLog(@"cut Selector");
          return NO;
      }
      else if (action == NSSelectorFromString(@"_define:"))
      {
          NSLog(@"define Selector");
          return NO;
      }
      else if (action == @selector(paste:))
      {
          NSLog(@"paste Selector");
          return NO;
      }
      else
      {
          return [super canPerformAction:action withSender:sender];
      }
    
    
    }
    

    and add another method to replace canPerformAction:withSender: with mightPerformAction:withSender:

    - (void) replaceUIWebBrowserView: (UIView *)view
    {
    
    //Iterate through subviews recursively looking for UIWebBrowserView
    for (UIView *sub in view.subviews) {
        [self replaceUIWebBrowserView:sub];
        if ([NSStringFromClass([sub class]) isEqualToString:@"UIWebBrowserView"]) {
    
            Class class = sub.class;
    
            SEL originalSelector = @selector(canPerformAction:withSender:);
            SEL swizzledSelector = @selector(mightPerformAction:withSender:);
    
            Method originalMethod = class_getInstanceMethod(class, originalSelector);
            Method swizzledMethod = class_getInstanceMethod(self.class, swizzledSelector);
    
            //add the method mightPerformAction:withSender: to UIWebBrowserView
            BOOL didAddMethod =
            class_addMethod(class,
                            originalSelector,
                            method_getImplementation(swizzledMethod),
                            method_getTypeEncoding(swizzledMethod));
            //replace canPerformAction:withSender: with mightPerformAction:withSender:
            if (didAddMethod) {
                class_replaceMethod(class,
                                    swizzledSelector,
                                    method_getImplementation(originalMethod),
                                    method_getTypeEncoding(originalMethod));
    
            } else {
    
                method_exchangeImplementations(originalMethod, swizzledMethod);
            }
        }
    }
    }
    

    And finally call it in the viewDidLoad of the ViewController:

    [self replaceUIWebBrowserView:self.webView];
    

    Note: Add #import to your viewController then error(Method) will not shown.

    Note: I am using NSSelectorFromString method to avoid detection of private API selectors during the review process.

    This seems to be working fine in iOS7 with Xcode 5, if anyone can find any issues in this please let me know how I can improve it..

提交回复
热议问题