动态 SwiftUI 颜色到 UIColor

问题描述 投票:0回答:1

我正在尝试将

Color
转换为
UIColor
。不幸的是,当 SwiftUI 颜色是动态的(浅色和深色的值不同)时,创建的 UIColor 不是动态的。

这是一些代码示例来说明问题:

let lightTraits = UITraitCollection(userInterfaceStyle: .light)
let darkTraits = UITraitCollection(userInterfaceStyle: .dark)

let uiColor = UIColor(dynamicProvider: {
    $0.userInterfaceStyle == .dark ? .red : .yellow
})
uiColor.resolvedColor(with: lightTraits).hexadecimalRepresentation // #FFFF00 (== .yellow: OK)
uiColor.resolvedColor(with: darkTraits).hexadecimalRepresentation // #FF0000 (== .red: OK)

let color = Color(uiColor: uiColor)
let invalidColor = UIColor(color)
invalidColor.resolvedColor(with: lightTraits).hexadecimalRepresentation // #FFFF00 ( == .yellow: OK)
invalidColor.resolvedColor(with: darkTraits).hexadecimalRepresentation // #FFFF00 (.yellow ??)


extension UIColor {
    var hexadecimalRepresentation: String? {
    
        var r: CGFloat = 0
        var g: CGFloat = 0
        var b: CGFloat = 0
        var a: CGFloat = 0

        getRed(&r, green: &g, blue: &b, alpha: &a)
        return String(format: "#%02lX%02lX%02lX", lroundf(Float(r) * 255), lroundf(Float(g) * 255), lroundf(Float(b) * 255))
    }
}

我相信

UIColor(_ color: Color)
仅读取一种配色方案的颜色...

ios swift swiftui uikit
1个回答
0
投票

TLDR:发生这种情况的原因是

uiColor.resolvedColor(with: darkTraits)
在评估时没有对
SwiftUI.Color
应用“环境”。

您可以从

cgColor
获取某个
SwiftUI.Color
colorScheme
值,如下所示: [旁注:iOS 17+!]

var env = EnvironmentValues()
env.colorScheme = .dark // or .light
let resolved = color.resolve(in: env)
print(resolved.cgColor.components)

因此,理想情况下,您将从

SwiftUI.Color
获取颜色分量,然后再将其转换为
UIColor
。或者您始终可以将
UIColor
转换回
SwiftUI.Color
。我用多层来回转换对其进行了测试。

至于为什么这不能按预期工作,这是我的猜测。

  1. A
    SwiftUI.Color
    View
    。它不是您通常认为的意义上的“颜色”。这是一个“应该用颜色绘制的 SwiftUI 视图”。
  2. SwiftUI 的架构方法。它是明确构建的声明式。视图实例说:“这是我的视图结构”。这又意味着
    SwiftUI.View
    不是可见视图。它是对应该绘制的东西的结构的声明。
  3. 这会产生一个后果:您不打算从视图中读取值。从架构上来说,
    SwiftUI
    视图的实例仅在提供环境和状态时才有意义。

将你的问题放入上下文中:我们采用一个

SwiftUI.Color
,这是一个
SwiftUI.View
,这是结构的定义,它需要一个环境和一个状态来表示某些东西。我们将其放入
UIColor
中,并在该环境和状态上下文之外检查/评估它。这到底是什么意思?

我们尝试通过

uiColor.resolvedColor(with: darkTraits)
模拟环境,但显然 UIColor 不会将其转换为环境。

这引导我们找到上面的解决方案:我们采用

SwiftUI.Color
并通过应用具有深色配色方案的环境来解决它。

© www.soinside.com 2019 - 2024. All rights reserved.