CustomWebView.h:
#import <UIKit/UIKit.h> @interface CustomUIWebView : UIWebView @end@H_301_5@CustomWebView.m:
#import <Foundation/Foundation.h> #import "CustomUIWebView.h" @implementation CustomUIWebView -(BOOL)canPerformAction:(SEL)action withSender:(id)sender { return NO; return [super canPerformAction:action withSender:sender]; } @end@H_301_5@
解决方法
这样做的主要原因是我们必须覆盖主要第一响应者的canPerformAction.从控制器调用[[[UIApplication sharedApplication] keyWindow] performSelector:@selector(firstResponder)]会通知我们UIWebBrowserView是实际的主要第一响应者.我们想要子类化UIWebBrowserView,但由于它是私有类,我们可能会在审核过程中拒绝Apple拒绝我们的应用程序.来自@Shayan RC的This answer建议执行一个方法调整以允许重写此方法而无需子类化UIWebBrowserView(从而防止App Store拒绝).
解决方案
我们的想法是添加一个替代canPerformAction的新方法.我创建了一个包含我们想要保留在菜单中的所有方法签名的数组.要删除样式选项,我们只需要将@“_ showTextStyleOptions:”添加到此数组中.添加要显示的所有其他方法签名(我已添加了签名的NSLog,以便您可以选择所需的方法签名).
- (BOOL) mightPerformAction:(SEL)action withSender:(id)sender { NSLog(@"action : %@",NSStringFromSelector(action)); NSArray<NSString*> *selectorsToKeep = @[@"cut:",@"copy:",@"select:",@"selectAll:",@"_lookup:"]; //add in this array every action you want to keep if ([selectorsToKeep containsObject:NSStringFromSelector(action)]) { return YES; } return NO; }@H_301_5@现在我们可以使用以下方法(来自@Shayan RC的答案)执行方法调配来调用前一个方法而不是canPerformAction.这将需要添加#import< objc / runtime.h>.
- (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); } } } }@H_301_5@最后,在viewDidLoad中调用prevIoUs方法,如下所示:[self replaceUIWebBrowserView:_webView].
方法调整似乎很难,但它允许您将代码保存在视图控制器中.如果您在实施以前的代码时遇到任何困难,请告诉我.
注意:使用WKWebView比使用UIWebView更容易实现此行为,并且不推荐使用UIWebView,您应该考虑切换到WKWebView.