在SwiftUI中使用十六进制颜色

Sin*_*N75 9 uicolor ios swiftui

在UIKit中,我们可以使用扩展将十六进制颜色设置为几乎所有内容。 https://www.hackingwithswift.com/example-code/uicolor/how-to-convert-a-hex-color-to-a-uicolor

但是当我尝试在SwiftUI上执行此操作时,这是不可能的,看起来SwiftUI没有将UIColor作为参数。

    Text(text)
        .color(UIColor.init(hex: "FFF"))
Run Code Online (Sandbox Code Playgroud)

错误信息:

Cannot convert value of type 'UIColor' to expected argument type 'Color?'
Run Code Online (Sandbox Code Playgroud)

我什至尝试为Color而不是进行扩展UIColor,但我没有任何运气

我对颜色的扩展:

导入SwiftUI

extension Color {
    init(hex: String) {
        let scanner = Scanner(string: hex)
        scanner.scanLocation = 0
        var rgbValue: UInt64 = 0
        scanner.scanHexInt64(&rgbValue)

        let r = (rgbValue & 0xff0000) >> 16
        let g = (rgbValue & 0xff00) >> 8
        let b = rgbValue & 0xff

        self.init(
            red: CGFloat(r) / 0xff,
            green: CGFloat(g) / 0xff,
            blue: CGFloat(b) / 0xff, alpha: 1
        )
    }
}
Run Code Online (Sandbox Code Playgroud)

错误信息:

Incorrect argument labels in call (have 'red:green:blue:alpha:', expected '_:red:green:blue:opacity:')
Run Code Online (Sandbox Code Playgroud)

Ste*_*fan 28

这是一个带有我的解决方案的游乐场。它在回退之后添加回退,并且只依赖于颜色和 alpha 的 hexString。

import SwiftUI

extension Color {
    init(hex string: String) {
        var string: String = string.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
        if string.hasPrefix("#") {
            _ = string.removeFirst()
        }

        // Double the last value if incomplete hex
        if !string.count.isMultiple(of: 2), let last = string.last {
            string.append(last)
        }

        // Fix invalid values
        if string.count > 8 {
            string = String(string.prefix(8))
        }

        // Scanner creation
        let scanner = Scanner(string: string)

        var color: UInt64 = 0
        scanner.scanHexInt64(&color)

        if string.count == 2 {
            let mask = 0xFF

            let g = Int(color) & mask

            let gray = Double(g) / 255.0

            self.init(.sRGB, red: gray, green: gray, blue: gray, opacity: 1)

        } else if string.count == 4 {
            let mask = 0x00FF

            let g = Int(color >> 8) & mask
            let a = Int(color) & mask

            let gray = Double(g) / 255.0
            let alpha = Double(a) / 255.0

            self.init(.sRGB, red: gray, green: gray, blue: gray, opacity: alpha)

        } else if string.count == 6 {
            let mask = 0x0000FF
            let r = Int(color >> 16) & mask
            let g = Int(color >> 8) & mask
            let b = Int(color) & mask

            let red = Double(r) / 255.0
            let green = Double(g) / 255.0
            let blue = Double(b) / 255.0

            self.init(.sRGB, red: red, green: green, blue: blue, opacity: 1)

        } else if string.count == 8 {
            let mask = 0x000000FF
            let r = Int(color >> 24) & mask
            let g = Int(color >> 16) & mask
            let b = Int(color >> 8) & mask
            let a = Int(color) & mask

            let red = Double(r) / 255.0
            let green = Double(g) / 255.0
            let blue = Double(b) / 255.0
            let alpha = Double(a) / 255.0

            self.init(.sRGB, red: red, green: green, blue: blue, opacity: alpha)

        } else {
            self.init(.sRGB, red: 1, green: 1, blue: 1, opacity: 1)
        }
    }
}

let gray0 = Color(hex: "3f")
let gray1 = Color(hex: "#69")
let gray2 = Color(hex: "#6911")
let gray3 = Color(hex: "fff")
let red = Color(hex: "#FF000044s")
let green = Color(hex: "#00FF00")
let blue0 = Color(hex: "0000FF")
let blue1 = Color(hex: "0000F")
Run Code Online (Sandbox Code Playgroud)

为了从 Color 中获取 hexString ......好吧,这不是一个公共 API。我们仍然需要依赖 UIColor 实现。

PS:我看到了下面的组件解决方案..但是如果将来API发生变化,我的版本会更稳定一些。

  • 这是这里最好的答案。如果添加不透明度作为参数,它将是最完整的一个。 (2认同)
  • 同意,我已经尝试了多种解决方案,这是这里的最佳答案。我不知道为什么它没有得到更多的支持。道具@Stefan!至于不透明度,只需像通常在 SwiftUI 中那样链接它... Color(hex: "#003366").opacity(0.2) (2认同)

Hao*_*Hao 26

最佳实践

此方法是在应用程序中设置自定义颜色的预期方法。设置后,可以在所有视图中访问颜色并轻松更新。也是一行代码。

  1. 从项目文件所在的左侧面板中打开“资产”文件夹

颜色设置示例

  1. 现在,在资源文件夹中,左侧应该有一个“+”按钮,单击该按钮并选择“颜色设置”。打开后,将其重命名为“Color1”

颜色设置示例

  1. 现在单击页面中间的颜色方块,然后从右侧的检查器面板中单击“显示颜色面板”,选择所需的颜色。

颜色设置示例

  1. 现在返回到要更改文本颜色的代码。

    Text
    .foregroundColor(Color("Color1"))
    
    Run Code Online (Sandbox Code Playgroud)


Kar*_*eri 9

尝试这个

extension Color {
init(hex: Int, opacity: Double = 1.0) {
    let red = Double((hex & 0xff0000) >> 16) / 255.0
    let green = Double((hex & 0xff00) >> 8) / 255.0
    let blue = Double((hex & 0xff) >> 0) / 255.0
    self.init(.sRGB, red: red, green: green, blue: blue, opacity: opacity)
}
}
Run Code Online (Sandbox Code Playgroud)

Text("Hello World!")
            .background(Color(hex: 0xf5bc53))

Text("Hello World!")
            .background(Color(hex: 0xf5bc53, opacity: 0.8))
Run Code Online (Sandbox Code Playgroud)


kon*_*iki 8

您快到了,您使用了错误的初始化参数:

extension Color {
    init(hex: String) {
        let scanner = Scanner(string: hex)
        scanner.scanLocation = 0
        var rgbValue: UInt64 = 0
        scanner.scanHexInt64(&rgbValue)

        let r = (rgbValue & 0xff0000) >> 16
        let g = (rgbValue & 0xff00) >> 8
        let b = rgbValue & 0xff


        self.init(red: Double(r) / 0xff, green: Double(g) / 0xff, blue: Double(b) / 0xff)

    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我尝试使用 Color("ff00ff") 并且工作得很好。你以十六进制形式传递什么? (3认同)
  • 它解决了编译错误,谢谢,但它没有设置 SwiftUI 中视图的颜色,没有错误但没有结果 (2认同)

Tol*_*kan 5

Another alternative below that uses Int for hex but of course, it can be changed to String if you prefer that.

extension Color {
    init(hex: Int, alpha: Double = 1) {
        let components = (
            R: Double((hex >> 16) & 0xff) / 255,
            G: Double((hex >> 08) & 0xff) / 255,
            B: Double((hex >> 00) & 0xff) / 255
        )
        self.init(
            .sRGB,
            red: components.R,
            green: components.G,
            blue: components.B,
            opacity: alpha
        )
    }
}
Run Code Online (Sandbox Code Playgroud)

Usage examples:

Color(hex: 0x000000)
Color(hex: 0x000000, alpha: 0.2)
Run Code Online (Sandbox Code Playgroud)

  • 对于任何感兴趣的人,此方法在《Swift 编程语言》一书中的 [高级运算符](https://docs.swift.org/swift-book/LanguageGuide/AdvancedOperators.html) 中进行了解释(在与 SwiftUI 无关的一般上下文中) #)。整章值得一读。提示:理解的关键是右移和按位与,最简单的例子是 1. 使用右移将数字减半 (number >> 1) 和 2. 检查数字是否为奇数 (number & 0x1 == 1)。 [Bitwise_operation](https://en.wikipedia.org/wiki/Bitwise_operation) 维基百科文章也值得阅读。 (2认同)