我似乎无法从UIWebView中删除粗体,斜体和下划线选项。为什么这不可能呢?
CustomWebView.h:
#import <UIKit/UIKit.h>
@interface CustomUIWebView : UIWebView
@end
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
答案 0 :(得分:2)
为了解决这个问题,我进行了很多研究,终于找到了解决方案。我首先尽管在包含- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
的{{1}}中覆盖UIViewController
就足以防止显示文本样式选项。但是不幸的是,这并不像看起来那样容易。
主要原因是我们必须覆盖主要第一响应者的UIWebView
。从控制器调用canPerformAction
会告诉我们[[[UIApplication sharedApplication] keyWindow] performSelector:@selector(firstResponder)]
是实际的主要第一响应者。我们希望将UIWebBrowserView
子类化,但是由于它是私有类,因此我们的应用可能会在审查过程中被Apple拒绝。来自@Shayan RC的This answer建议执行一种方法转换,以允许在不继承UIWebBrowserView
子类的情况下重写该方法(从而防止被App Store拒绝)。
想法是添加一个新方法来代替UIWebBrowserView
。我创建了一个数组,其中包含我们要保留在菜单中的所有方法签名。要删除样式选项,我们只需不必向该数组添加canPerformAction
。添加您要显示的所有其他方法签名(我添加了@"_showTextStyleOptions:"
个签名,以便您可以选择想要的签名)。
NSLog
现在,我们可以使用以下方法(从@Shayan RC的回答)执行方法转换以调用先前的方法而不是- (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;
}
。这将需要添加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);
}
}
}
}
调用viewDidLoad
中的先前方法。
方法混乱似乎很难,但是它允许您将代码保留在视图控制器中。请告诉我您在实施以前的代码时是否遇到任何困难。
注意:与[self replaceUIWebBrowserView:_webView]
相比,WKWebView
更容易实现此行为,并且UIWebView
已过时,您应该考虑切换到UIWebView
。