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

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

更改色调颜色不起作用。 将css应用于::selection-webkit-tap-highlight-color标签既-webkit-tap-highlight-color也不适用。

在此处输入图像描述

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

这是它的示例代码。

 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')"]; 

在此处输入图像描述

这是我在私人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 /源极/ WebKit2 / WebKit2-7601.1.46.9 / UIProcess / IOS / WKContentViewInteraction.mm.auto.html

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

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

最终的解决方案在iOS WKWebView 得到validation ,一旦颜色被覆盖,它将影响所有WKWebView实例。 原始高亮颜色在UIWKSelectionViewUIWebTextRangeView硬编码,并通过UIKit私有方法 +[UIColor selectionHighlightColor] ,产生RGBA 0 0.33 0.65 0.2

实际的代码(我选择了obj-c以便于调整,但这也可以在Swift完成):

 #import "ViewController.h" #import  @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