如何将 UIColor 转换为十六进制并在 NSLog 中显示



我已经检查了几个关于如何将 UIColor 代码转换为十六进制的链接,但我不确定如何调用该方法以在 NSLog 中显示它们。我没有评论的声誉,所以作为问题发布是我最后的手段。我希望它在日志中运行我的应用程序时显示。

其次,我在哪里输入RGB色号(R = 30,G = 171,B = 13(?我看到所有示例都使用数组 [0]、[1]、[2],它通常是指索引位置,那么我在哪里添加颜色值呢?

我有这个代码:

- (NSString *) hexFromUIColor:(UIColor *)color {
    if (CGColorGetNumberOfComponents(color.CGColor) < 4) {
        const CGFloat *components = CGColorGetComponents(color.CGColor);
        color = [UIColor colorWithRed:components[30] green:components[141] blue:components[13] alpha:components[1]];
    }
    if (CGColorSpaceGetModel(CGColorGetColorSpace(color.CGColor)) != kCGColorSpaceModelRGB) {
        return [NSString stringWithFormat:@"#FFFFFF"];
    }
    return [NSString stringWithFormat:@"#%02X%02X%02X", (int)((CGColorGetComponents(color.CGColor))[0]*255.0), (int)((CGColorGetComponents(color.CGColor))[1]*255.0), (int)((CGColorGetComponents(color.CGColor))[2]*255.0)];
}

我检查过的链接:

来自 uicolor 的十六进制颜色

如何将十六进制 RGB 颜色代码转换为 UIColor?

我尝试在viewDidLoad中调用该方法,但是如果没有UIColor,它将无法工作。我相信这很简单。

感谢任何回答的人。

我在 viewDidLoad 中使用什么代码来调用此方法以便在 NSLog 中显示?

Swift 5:

func hexStringFromColor(color: UIColor) -> String {
    let components = color.cgColor.components
    let r: CGFloat = components?[0] ?? 0.0
    let g: CGFloat = components?[1] ?? 0.0
    let b: CGFloat = components?[2] ?? 0.0
    let hexString = String.init(format: "#%02lX%02lX%02lX", lroundf(Float(r * 255)), lroundf(Float(g * 255)), lroundf(Float(b * 255)))
    print(hexString)
    return hexString
 }
func colorWithHexString(hexString: String) -> UIColor {
    var colorString = hexString.trimmingCharacters(in: .whitespacesAndNewlines)
    colorString = colorString.replacingOccurrences(of: "#", with: "").uppercased()
    print(colorString)
    let alpha: CGFloat = 1.0
    let red: CGFloat = self.colorComponentFrom(colorString: colorString, start: 0, length: 2)
    let green: CGFloat = self.colorComponentFrom(colorString: colorString, start: 2, length: 2)
    let blue: CGFloat = self.colorComponentFrom(colorString: colorString, start: 4, length: 2)
    let color = UIColor(red: red, green: green, blue: blue, alpha: alpha)
    return color
}
func colorComponentFrom(colorString: String, start: Int, length: Int) -> CGFloat {
    let startIndex = colorString.index(colorString.startIndex, offsetBy: start)
    let endIndex = colorString.index(startIndex, offsetBy: length)
    let subString = colorString[startIndex..<endIndex]
    let fullHexString = length == 2 ? subString : "(subString)(subString)"
    var hexComponent: UInt32 = 0
    guard Scanner(string: String(fullHexString)).scanHexInt32(&hexComponent) else {
        return 0
    }
    let hexFloat: CGFloat = CGFloat(hexComponent)
    let floatValue: CGFloat = CGFloat(hexFloat / 255.0)
    print(floatValue)
    return floatValue
}

如何使用

let red =  CGFloat(30.0)
let green =  CGFloat(171.0)
let blue =  CGFloat(13.0)
let alpha =  CGFloat(1.0)
let color = UIColor(red: CGFloat(red/255.0), green: CGFloat(green/255.0), blue: CGFloat(blue / 255.0), alpha: alpha)
let colorCode = self.hexStringFromColor(color: color)
print(colorCode)
let resultColor = self.colorWithHexString(hexString: colorCode)
print(resultColor)

目标-C:

- (NSString *)hexStringFromColor:(UIColor *)color {
    const CGFloat *components = CGColorGetComponents(color.CGColor);
    CGFloat r = components[0];
    CGFloat g = components[1];
    CGFloat b = components[2];
    return [NSString stringWithFormat:@"#%02lX%02lX%02lX",
            lroundf(r * 255),
            lroundf(g * 255),
            lroundf(b * 255)];
}

获取十六进制代码字符串后,调用下面的方法以获取UIColor

- (UIColor *) colorWithHexString: (NSString *) hexString
{
    NSString *colorString = [[hexString stringByReplacingOccurrencesOfString: @"#" withString: @""] uppercaseString];
    NSLog(@"colorString :%@",colorString);
    CGFloat alpha, red, blue, green;
    // #RGB
    alpha = 1.0f;
    red   = [self colorComponentFrom: colorString start: 0 length: 2];
    green = [self colorComponentFrom: colorString start: 2 length: 2];
    blue  = [self colorComponentFrom: colorString start: 4 length: 2];
    return [UIColor colorWithRed: red green: green blue: blue alpha: alpha];
}

- (CGFloat) colorComponentFrom: (NSString *) string start: (NSUInteger) start length: (NSUInteger) length {
    NSString *substring = [string substringWithRange: NSMakeRange(start, length)];
    NSString *fullHex = length == 2 ? substring : [NSString stringWithFormat: @"%@%@", substring, substring];
    unsigned hexComponent;
    [[NSScanner scannerWithString: fullHex] scanHexInt: &hexComponent];
    return hexComponent / 255.0;
}

如何使用

// ( R = 30, G = 171, B = 13)? 
CGFloat red = 30.0;
CGFloat green = 171.0;
CGFloat blue = 13.0; 
CGFloat alpha = 255.0
UIColor *color = [UIColor colorWithRed:(red/255.0) green:(green/255.0) blue:(blue/255.0) alpha:(alpha/255.0)];
NSString *colorCode = [self hexStringFromColor:color];
NSLog(@"Color Code: %@", colorCode);
UIColor *resultColor = [self colorWithHexString:colorCode];

最后是使用 alpha 分量并使用右乘数的版本

extension UIColor {
    var hexString: String? {
        var red: CGFloat = 0
        var green: CGFloat = 0
        var blue: CGFloat = 0
        var alpha: CGFloat = 0
        let multiplier = CGFloat(255.999999)
        guard self.getRed(&red, green: &green, blue: &blue, alpha: &alpha) else {
            return nil
        }
        if alpha == 1.0 {
            return String(
                format: "#%02lX%02lX%02lX",
                Int(red * multiplier),
                Int(green * multiplier),
                Int(blue * multiplier)
            )
        }
        else {
            return String(
                format: "#%02lX%02lX%02lX%02lX",
                Int(red * multiplier),
                Int(green * multiplier),
                Int(blue * multiplier),
                Int(alpha * multiplier)
            )
        }
    }
}

> Kampai的答案适用于RGB颜色,但不适用于单色(UIColor colorWithWhite:alpha:(。它也不处理HEX支持的alpha。下面是hexStringFromColor的略微修改版本:

+ (NSString *)hexStringFromColor:(UIColor *)color
{
    CGColorSpaceModel colorSpace = CGColorSpaceGetModel(CGColorGetColorSpace(color.CGColor));
    const CGFloat *components = CGColorGetComponents(color.CGColor);
    CGFloat r, g, b, a;
    if (colorSpace == kCGColorSpaceModelMonochrome) {
        r = components[0];
        g = components[0];
        b = components[0];
        a = components[1];
    }
    else if (colorSpace == kCGColorSpaceModelRGB) {
        r = components[0];
        g = components[1];
        b = components[2];
        a = components[3];
    }
    return [NSString stringWithFormat:@"#%02lX%02lX%02lX%02lX",
            lroundf(r * 255),
            lroundf(g * 255),
            lroundf(b * 255),
            lroundf(a * 255)];
}

其他 Swift 回答 UI 像 white 这样的 UIColors 崩溃,其中 CGColor 只返回了 2 个组件。

这是一个 Swift 4 版本,它没有这个问题,如果需要,还会在字符串末尾返回透明度信息(Web 格式(。

在生成十六进制字符串之前,首先将颜色转换为 sRGB 颜色空间,以便即使在灰度或其他颜色空间中也能正常工作。

例如:

白色会回来 #FFFFFF

不透明度为 50% 的白色将返回 #FFFFFF7F

extension UIColor {
    var hexString: String {
        let cgColorInRGB = cgColor.converted(to: CGColorSpace(name: CGColorSpace.sRGB)!, intent: .defaultIntent, options: nil)!
        let colorRef = cgColorInRGB.components
        let r = colorRef?[0] ?? 0
        let g = colorRef?[1] ?? 0
        let b = ((colorRef?.count ?? 0) > 2 ? colorRef?[2] : g) ?? 0
        let a = cgColor.alpha
        var color = String(
            format: "#%02lX%02lX%02lX",
            lroundf(Float(r * 255)),
            lroundf(Float(g * 255)),
            lroundf(Float(b * 255))
        )
        if a < 1 {
            color += String(format: "%02lX", lroundf(Float(a * 255)))
        }
        return color
    }
}

旧版本

此版本无法在非 RGB 色彩空间中正确处理某些颜色。

extension UIColor {
    var hexString: String {
        let colorRef = cgColor.components
        let r = colorRef?[0] ?? 0
        let g = colorRef?[1] ?? 0
        let b = ((colorRef?.count ?? 0) > 2 ? colorRef?[2] : g) ?? 0
        let a = cgColor.alpha
        var color = String(
            format: "#%02lX%02lX%02lX",
            lroundf(Float(r * 255)),
            lroundf(Float(g * 255)),
            lroundf(Float(b * 255))
        )
        if a < 1 {
            color += String(format: "%02lX", lroundf(Float(a)))
        }
        return color
    }
}

Swift way:

extension UIColor {
    var hexString: String {
        cgColor.components![0..<3]
            .map { String(format: "%02lX", Int($0 * 255)) }
            .reduce("#", +)
    }
}

如果您需要带有 alpha 的十六进制,只需从代码中删除[0..<3]即可。

另一个更安全的实现,可以很好地处理一种组件颜色(如UIColor.white,UIColor.black(:

    var hexString: String {
        var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0
        getRed(&r, green: &g, blue: &b, alpha: nil)
        return [r, g, b].map { String(format: "%02lX", Int($0 * 255)) }.reduce("#", +)
    }
extension UIColor {
    var hexString: String? {
        guard let components = self.cgColor.components else { return nil }
        let red = Float(components[0])
        let green = Float(components[1])
        let blue = Float(components[2])
        return String(format: "#%02lX%02lX%02lX", lroundf(red * 255), lroundf(green * 255), lroundf(blue * 255))
    }
}

在 Swift 中,我只是简单地创建了一个 UIColor 的扩展......

extension UIColor
{
    var hexString:NSString {
        let colorRef = CGColorGetComponents(self.CGColor)
        let r:CGFloat = colorRef[0]
        let g:CGFloat = colorRef[1]
        let b:CGFloat = colorRef[2]
        return NSString(format: "#%02lX%02lX%02lX", lroundf(Float(r * 255)), lroundf(Float(g * 255)), lroundf(Float(b * 255)))
    }
}

基于Kampai的回答,这里是SwiftUI版本。

extension Color {
    func hexString() -> String {
        let components = self.cgColor?.components
        let r: CGFloat = components?[0] ?? 0.0
        let g: CGFloat = components?[1] ?? 0.0
        let b: CGFloat = components?[2] ?? 0.0
        let hexString = String.init(format: "#%02lX%02lX%02lX", lroundf(Float(r * 255)), lroundf(Float(g * 255)), lroundf(Float(b * 255)))
        return hexString
    }
}

如果您需要Android的颜色,这是正确的顺序。 阿尔法先行:

extension UIColor {
    var hexString: String? {
        var red: CGFloat = 0
        var green: CGFloat = 0
        var blue: CGFloat = 0
        var alpha: CGFloat = 0
        let multiplier = CGFloat(255.999999)
        guard self.getRed(&red, green: &green, blue: &blue, alpha: &alpha) else {
            return nil
        }
        if alpha == 1.0 {
            return String(
                format: "#%02lX%02lX%02lX",
                Int(red * multiplier),
                Int(green * multiplier),
                Int(blue * multiplier)
            )
        }
        else {
            return String(
                format: "#%02lX%02lX%02lX%02lX",
                Int(alpha * multiplier),
                Int(red * multiplier),
                Int(green * multiplier),
                Int(blue * multiplier)
            )
        }
    }
}

然后调用:

debugPrint("testColor > ", self.testColor().hexString!)
或者

,如果将此扩展用于UIColor,则可以使用.hexCode

喜欢这个:

extension UIColor {
    var hexCode: String {
        get{
            let colorComponents = self.cgColor.components!
            if colorComponents.count < 4 {
                return String(format: "%02x%02x%02x", Int(colorComponents[0]*255.0), Int(colorComponents[0]*255.0),Int(colorComponents[0]*255.0)).uppercased()
            }
            return String(format: "%02x%02x%02x", Int(colorComponents[0]*255.0), Int(colorComponents[1]*255.0),Int(colorComponents[2]*255.0)).uppercased()
        }
    }
}
var myColor: UIColor?
myColor = UIColor(red: 1, blue: 1, green: 1, alpha: 1.0)
print(myColor!.hexCode) // output: 
// if you use API, you can do something like this:
print("#(myColor!.hexCode)") // output: #FFFFFF

swift 2 答案转换为 swift 3

var hexString: String {
    let components = self.cgColor.components
    let red = Float((components?[0])!)
    let green = Float((components?[1])!)
    let blue = Float((components?[2])!)
    return String(format: "#%02lX%02lX%02lX", lroundf(red * 255), lroundf(green * 255), lroundf(blue * 255))
}
处理

alpha 时的潜在陷阱:十六进制字符串有不同的格式,有些格式的 alpha 位于十六进制字符串的开头,而其他格式的字母位于末尾。根据您的背景,您可能对十六进制字符串的格式有不同的想法。对于Android开发人员来说,它可能会在开始时与alpha一起,对于Web开发人员来说,它可能在字符串的末尾。因此,请始终说明十六进制字符串的格式以避免混淆。Android 十六进制字符串必须在开头包含 alpha。因此,当涉及到十六进制字符串时,这是人们可能会陷入的陷阱(我做到了(,因此说出预期的格式很重要。因此,如果您正在为iOS和Android开发应用程序,那么这个陷阱会怎样。

链接:https://en.wikipedia.org/wiki/RGBA_color_space 有关为什么十六进制字符串可能以不同方式格式化的详细信息,在某些情况下,alpha 在开头。安卓链接 https://developer.android.com/reference/android/graphics/Color.html 和 https://gist.github.com/lopspower/03fb1cc0ac9f32ef38f4

请注意 #AARRGGBB 十六进制字符串格式使用以下代码,使 Alpha 位于字符串的开头。

(注意:如果返回color == null黑色(。

+(NSString*)hexStringFromColor:(UIColor *)color
{
    CGFloat r = 0, g = 0, b = 0, a = 1;
    if (color) {
        [color getRed:&r green:&g blue:&b alpha:&a];
    }
    return [NSString stringWithFormat:@"#%02lX%02lX%02lX%02lX",
            lroundf(a * 255.0),
            lroundf(r * 255.0),
            lroundf(g * 255.0),
            lroundf(b * 255.0)
            ];
}

SwiftUI

P3 颜色十六进制

extension Color {
    var hex: String {
        guard let colorSpace = CGColorSpace(name: CGColorSpace.displayP3), let color = UIColor(self).cgColor.converted(to: colorSpace, intent: .defaultIntent, options: nil),
          let components = color.components, 3 <= components.count else { return "" }
        return String(format: "#%02lX%02lX%02lX%02lX", lroundf(Float(components[0] * 255)), lroundf(Float(components[1] * 255)), lroundf(Float(components[2] * 255)), lroundf(Float(components[3] * 255)))
     }
}

Swift 5

extension Collection {
    public subscript(safe index: Index) -> Element? {
        return startIndex <= index && index < endIndex ? self[index] : nil
    }
}
extension UIColor {
    var hexString: String {
        let components = cgColor.components
        let r: CGFloat = components?[safe: 0] ?? 0.0
        let g: CGFloat = components?[safe: 1] ?? 0.0
        let b: CGFloat = components?[safe: 2] ?? 0.0
        let hexString = String(format: "#%02lX%02lX%02lX", lroundf(Float(r * 255)), lroundf(Float(g * 255)),
                               lroundf(Float(b * 255)))
        return hexString
    }
}

最新更新