Swift 5 中带有动态 URL 的 WKWebView 明暗模式

Posted

技术标签:

【中文标题】Swift 5 中带有动态 URL 的 WKWebView 明暗模式【英文标题】:WKWebView Dark and Light Mode with dynamic URL in Swift 5 【发布时间】:2021-12-18 04:04:29 【问题描述】:

我创建了没有一个 url 的 WKWebView。用户将此 WKWebView 用作 Safari 意味着用户可以在 WKWebView 上搜索任何内容。当我更改深色和浅色模式时,我面临一个问题,我的 Web 视图将只显示白色(浅色)模式。我的应用程序在这两种模式下都可以正常工作,除了 WKWebView。

已在 SO 上搜索,但未找到任何相关问题。 how to use ios 13 darkmode for wkwebview

我参考了这个博客,但它是静态网址,所以它不会帮助我

https://useyourloaf.com/blog/using-dynamic-type-with-web-views/

还检查了 opaque 和 background 属性,但对我不起作用!

重要 用户可以搜索 google.com、照片或任何冲浪等任何内容。

class DownloadViewController: UIViewController 
    
    @IBOutlet weak var webView: WKWebView!

    override func viewDidLoad() 
        super.viewDidLoad()
        webView.uiDelegate = self
        webView.navigationDelegate = self
        webView.load(URLRequest(url: URL(string: "https://www.google.com")!))
        webView.allowsBackForwardNavigationGestures = true
        webView.allowsLinkPreview = true
    


首先我加载谷歌网站然后依赖于用户(这里完全动态不是一个网址)。

请给我建议!谢谢。

【问题讨论】:

【参考方案1】:

您可以使用注入 CSS 技术为您加载的网页添加亮/暗功能,例如:

// Load a web page
webView?.load(URLRequest(url: URL(string: "https://google.com")!))

// Inject Light/Dark CSS

let lightDarkCSS = ":root  color-scheme: light dark; "
let base64 = lightDarkCSS.data(using: .utf8)!.base64EncodedString()

let script = """
    javascript:(function() 
        var parent = document.getElementsByTagName('head').item(0);
        var style = document.createElement('style');
        style.type = 'text/css';
        style.innerhtml = window.atob('\(base64)');
        parent.appendChild(style);
    )()
"""

let cssScript = WKUserScript(source: script, injectionTime: .atDocumentEnd, forMainFrameOnly: false)
webView?.configuration.userContentController.addUserScript(cssScript)

结果:

要支持页面更改,您可以将插入代码移动到didCommitNavigation 通知:

func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) 
    ...
    // Inject CSS here

注意:它通常不适用于任何网页,因为某些网站可以硬编码背景颜色、字体等,但您也可以通过覆盖其 CSS 来调整特定页面。

【讨论】:

它只适用于谷歌。那么如果我想对任何网页 Inject 或 interfaceStyle 执行哪种方法是正确的? @YogeshPatel 它可以处理没有硬编码背景颜色等的网页,但是您可以动态注入 CSS 并仅覆盖某些网站的已知样式,因此没有通用的解决方案我在上面提到过。 好的明白了!【参考方案2】:

已在 SO 上搜索,但未找到任何相关问题。

您提到这一点很有趣,因为这个问题已经解决了好几次了。快速搜索将显示许多好的答案和主题,例如:this one。

话虽如此,快速回答是:

WKWebView 可以像其他UIView/NSView 一样采用明暗模式。您可以在外观上手动设置interfaceStyle,否则它会继承它。更多细节在这里overrideUserInterfaceStyle。

但是

您可能面临的问题是,即使WKWebView 使用的是dark interfaceStyle,网站仍会以浅色模式显示。那是因为这些网站(谷歌和任何其他网站/URL)是独立的并且可以自己处理他们的风格。其中一些会调整以匹配您设备的界面风格,但不是全部。简而言之,即使WKWebView 处于深色模式,Google 也会根据需要加载白色背景。

正如其他人所提到的,您可以通过手动注入 CSS 来更改此行为,如果您想要这样做,请检查这些答案,还请检查我在此答案开头发布的链接,他们讨论了该方法。

【讨论】:

我检查过但它不起作用***.com/questions/57203909/… @YogeshPatel 您需要手动注入 CSS,可能是通过 JavaScript。每个网站都是不同的,因此它可能适用于某些人但不适用于其他人,它并不是很简单,并且可以有许多不同的方法。很难说出究竟是什么不适合您,请发布您的 Swift 代码、JavaScript 代码、CSS 代码以及您尝试使用该代码修改的网站。到目前为止发布的代码你甚至还没有开始尝试注入任何东西。 我尝试了许多 css 代码,但它不起作用,所以没有提到该代码,因为它不适用于 @iuril 代码的谷歌网站,它只适用于谷歌。那么如果我想对任何网页 Inject 或 interfaceStyle 做哪种方法是正确的?【参考方案3】:

android web 视图 (force_darkmode) 一样,Apple 尚未提供对暗模式 web 视图的支持。您可以通过一些知名网站探索 safari,即使它们没有转换为暗模式。 所以 我们应该等待 Webkit 暗模式支持 到那时。这些 CSS 注入不是最佳实践或稳健的解决方案。

【讨论】:

以上是关于Swift 5 中带有动态 URL 的 WKWebView 明暗模式的主要内容,如果未能解决你的问题,请参考以下文章

Swift 4.2 中带有 JSON 数据的 Tableview

Redirect::route 在 Laravel 5 中的 URL 中带有参数

Laravel 5中带有可选参数的url中的两个斜杠

Laravel 5.2 中带有 javascript 的模态视图中的动态图像

将 URL 回显到网络驱动器上名称中带有空格的文件

从 iOS Swift 中的 cam 扫描仪 SDK 返回时,WKwebview 是空白屏幕?