第一个解决方案不起作用的根本原因是名为UIWebBrowserView 的子视图。对于上下文菜单中显示的任何action,这似乎是其 canPerformAction 返回 true 的视图。
由于这个UIWebBrowserView 是一个私有类,我们不应该尝试继承它(因为它会导致您的应用被拒绝)。
所以我们要做的是创建另一个名为mightPerformAction:withSender: 的方法,就像这样-
- (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];
}
}
并添加另一种方法以将 canPerformAction:withSender: 替换为 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);
}
}
}
}
最后在ViewController的viewDidLoad中调用:
[self replaceUIWebBrowserView:self.webView];
注意:将#import <objc/runtime.h> 添加到您的viewController 将不会显示错误(方法)。
注意:我使用NSSelectorFromString 方法来避免在审核过程中检测到私有API选择器。