如何获取适配明暗模式的系统颜色十六进制值适配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
相关产品推荐
相关产品推荐

