【问题标题】:Remove Bold, Italic, and Underline options from the UIWebView in iOS从 iOS 中的 UIWebView 中删除粗体、斜体和下划线选项
【发布时间】:2019-01-13 22:10:51
【问题描述】:

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

【问题讨论】:

  • 好吧,你不能继承 UIWebView,而且 UIWebView 本身已被弃用,所以这是两个错误。
  • 是的,我计划在时间允许时迁移到 WKWebView,我现在只需要快速修复。所以不可能吗?
  • @JoshO'Connor 你检查了吗stackoverflow.com/a/6051172/2776008
  • 是的,但它不起作用,因为我需要能够选择 uiwebview

标签: ios


【解决方案1】:

为了解决这个问题,我进行了很多调查,最终找到了解决方案。我首先虽然在包含UIWebViewUIViewController 中覆盖- (BOOL)canPerformAction:(SEL)action withSender:(id)sender 足以防止出现文本样式选项。但不幸的是,这并不像看起来那么容易。

这样做的主要原因是我们必须覆盖主要第一响应者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;
}

现在我们可以使用以下方法(来自@Shayan RC 的答案)执行方法调配来调用先前的方法而不是canPerformAction。这需要添加#import &lt;objc/runtime.h&gt;

- (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,您真的应该考虑切换到WKWebView

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-25
    • 1970-01-01
    • 2011-03-03
    • 1970-01-01
    • 2021-08-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多