如何在WKWebView中更改文本选择颜色?

时间:2017-08-01 11:58:52

标签: ios objective-c swift webkit wkwebview

我正在尝试更改WKWebView中的文字选择颜色。我尝试了几乎所有我为UIWebView / WKWebView提出的解决方案。

更改色调颜色不起作用。对::selection应用css,-webkit-tap-highlight-color标记都不起作用。

enter image description here

总是蓝色的。是否有可能改变它?

3 个答案:

答案 0 :(得分:1)

以下是它的示例代码。

function highlight(colour) {
var range, sel;
if (window.getSelection) {
    // IE9 and non-IE
    try {
        if (!document.execCommand("BackColor", false, colour)) {
            makeEditableAndHighlight(colour);
        }
    } catch (ex) {
        makeEditableAndHighlight(colour)
    }
} else if (document.selection && document.selection.createRange) {
    // IE <= 8 case
    range = document.selection.createRange();
    range.execCommand("BackColor", false, colour);
}}

通过Objective-C代码调用此方法

[webView stringByEvaluatingJavaScriptFromString:@"highlight('#ff0')"];

答案 1 :(得分:1)

从iOS 13开始,设置WKWebView的if (@available(iOS 13.0, *)) { webView.tintColor = [webView.tintColor resolvedColorWithTraitCollection:[UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleLight]]; } 属性还会更改选择颜色(和插入符号的颜色)。

{{1}}

额外提示:如果您的应用程序支持暗模式,但由于某种原因WKWebView内容必须为亮模式,则可以强制包含WKWebView的整个视图控制器具有亮模式特征,或者可以执行以下操作:

{{1}}

这可确保选择和插入符号的颜色在html中带有“浅色”内容的情况下可见

答案 2 :(得分:0)

enter image description here

我在私人WebKit API hacky swizzling 明显不符合的AppStore应用程序。 Apple恰好为它提供了大量的开源代码: https://opensource.apple.com/source/WebKit2/WebKit2-7601.1.46.9/UIProcess/ios/WKContentViewInteraction.h.auto.html https://opensource.apple.com/source/WebKit2/WebKit2-7601.1.46.9/UIProcess/ios/WKContentViewInteraction.mm.auto.html

因此,html内容的实际选择亮点分两个阶段进行。在触摸屏上按住点按钮之前,会显示私人课程 UIWKSelectionView。重点恰好是它的tintView属性。每个tintView getter调用都会生成一个以高亮颜色为背景的新UIView实例。因此,覆盖需要在每次访问后发生。

在第二阶段(用户释放点击后),所选范围由私有类 UIWebTextRangeView表示。带点的文本垂直标记为UIWebDragDotView。突出显示发生在updateRectViews方法中,需要在进行颜色覆盖之前调用。

iOS 8 - 11 的最终解决方案已验证,一旦颜色被覆盖,它将影响所有WKWebView个实例。原始高光颜色在UIWKSelectionView&amp; UIWebTextRangeView并通过 UIKit私有方法 +[UIColor selectionHighlightColor]获取,产生RGBA 0 0.33 0.65 0.2

实际代码(我选择了obj-c以获得更好的方便,但这也可以在Swift中完成):

#import "ViewController.h"
#import <objc/runtime.h>

@import WebKit;
static IMP __original_Method_IMP_tintView;
static IMP __original_Method_IMP_updateRectViews;

//UIWebTextRangeView
void replacement_updateRectViews(UIView* self, SEL _cmd)
{
    ((void(*)(id,SEL))__original_Method_IMP_updateRectViews)(self, _cmd);
    for (UIView* view in self.subviews) {
        //isMemberOfClass would be used instead to filter out UIWebDragDotView if its color is meant to be unchanged
        if ([view isKindOfClass:NSClassFromString(@"UIWebDragDotView")]) {
            [view setValue:UIColor.redColor forKey:@"m_selectionBarColor"];
        } else {
            //These are UIView*
            view.backgroundColor = [UIColor colorWithRed:1.0 green:0 blue:0 alpha:0.2];
        }
    }
}

//UIWKSelectionView
UIView* replacement_tintView(id self, SEL _cmd)
{
    UIView* tintView = ((UIView*(*)(id,SEL))__original_Method_IMP_tintView)(self, _cmd);
    tintView.backgroundColor = [UIColor colorWithRed:1.0 green:0 blue:0 alpha:0.2]; 
    return tintView;
}

@interface ViewController ()
@end

@implementation ViewController
+ (void)load {
    __original_Method_IMP_tintView = method_setImplementation(class_getInstanceMethod(NSClassFromString(@"UIWKSelectionView"),NSSelectorFromString(@"tintView")), (IMP)replacement_tintView);
    __original_Method_IMP_updateRectViews = method_setImplementation(class_getInstanceMethod(NSClassFromString(@"UIWebTextRangeView"),NSSelectorFromString(@"updateRectViews")), (IMP)replacement_updateRectViews);
}

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view = [WKWebView new];
    [(WKWebView*)self.view loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://stackoverflow.com/"]]];
}
@end