从UIWebView(iOS)删除粗体,斜体和下划线选项

时间:2018-08-06 22:07:43

标签: ios

我似乎无法从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

enter image description here

1 个答案:

答案 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