You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取适配明暗模式的系统颜色十六进制值适配WKWebView

解决暗黑模式下获取系统颜色正确十六进制值的问题

你的核心问题在于:系统动态颜色(如UIColor.systemBackground、UIColor.label)需要根据当前外观模式解析出实际色值,但原代码没有传入对应的traitCollection,导致始终获取的是浅色模式下的默认值。

问题根源

系统动态颜色是环境依赖的,直接调用getRed(_:green:blue:alpha:)时,默认会使用当前线程的traitCollection,但在SwiftUI视图中直接转换时,可能没有正确关联当前外观模式的trait,导致解析出错误的色值。

解决方案

修改颜色转换函数,显式传入对应外观模式的traitCollection,通过resolvedColor(with:)方法获取当前模式下的实际颜色值。

1. 修正颜色转换函数

func convertUIColorToHex(_ uiColor: UIColor, traitCollection: UITraitCollection? = nil) -> String {
    // 根据传入的trait解析出当前模式下的实际颜色
    let resolvedColor = uiColor.resolvedColor(with: traitCollection ?? UITraitCollection.current)
    
    var red: CGFloat = 0
    var green: CGFloat = 0
    var blue: CGFloat = 0
    var alpha: CGFloat = 0
    
    resolvedColor.getRed(&red, green: &green, blue: &blue, alpha: &alpha)
    
    let redInt = Int(red * 255)
    let greenInt = Int(green * 255)
    let blueInt = Int(blue * 255)
    
    return String(format: "#%02X%02X%02X", redInt, greenInt, blueInt)
}

2. 在SwiftUI视图中使用修正后的函数

利用@Environment(\.colorScheme)生成对应外观模式的traitCollection,传入转换函数:

import SwiftUI

struct ColorView: View {
    @Environment(\.colorScheme) var colorScheme

    var body: some View {
        // 根据当前颜色方案生成对应的traitCollection
        let currentTrait = UITraitCollection(userInterfaceStyle: colorScheme == .dark ? .dark : .light)
        
        Text(colorScheme == .dark ? "暗黑模式下:" : "浅色模式下:")

        Text("背景色 \(convertUIColorToHex(UIColor.systemBackground, traitCollection: currentTrait))")
        Text("文字色 \(convertUIColorToHex(UIColor.label, traitCollection: currentTrait))")
        
        Text("上方文字的颜色和背景色与系统一致")
            .background(Color(UIColor.systemBackground))
            .foregroundColor(Color(UIColor.label))
            .padding(20)
            .border(.red)
    }
}

3. 适配WKWebView的场景

在WKWebView的SwiftUI封装中,监听颜色方案变化,动态生成带正确颜色的HTML:

import SwiftUI
import WebKit

struct AdaptiveWebView: UIViewRepresentable {
    @Environment(\.colorScheme) var colorScheme
    let content: String
    
    func makeUIView(context: Context) -> WKWebView {
        WKWebView()
    }
    
    func updateUIView(_ uiView: WKWebView, context: Context) {
        let currentTrait = UITraitCollection(userInterfaceStyle: colorScheme == .dark ? .dark : .light)
        let bgHex = convertUIColorToHex(UIColor.systemBackground, traitCollection: currentTrait)
        let textHex = convertUIColorToHex(UIColor.label, traitCollection: currentTrait)
        
        // 生成适配当前外观的HTML
        let styledHTML = """
        <html>
        <head>
            <style>
                body {
                    margin: 0;
                    padding: 16px;
                    background-color: \(bgHex);
                    color: \(textHex);
                    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
                }
            </style>
        </head>
        <body>
            \(content)
        </body>
        </html>
        """
        
        uiView.loadHTMLString(styledHTML, baseURL: nil)
    }
}

这样,当系统外观模式切换时,updateUIView会自动触发,重新加载带有正确颜色的HTML,让WKWebView完全适配应用的外观模式。

内容的提问来源于stack exchange,提问作者nirav dinmali

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 09:15:06