从Cocoa中的NSColor获取十六进制值?

4
有人知道在Cocoa中是否可以从NSColor获取十六进制颜色值吗?
6个回答

9

使用蓝色NSColor的示例:

NSColor* color = [NSColor blueColor];

NSString* hexString = [NSString stringWithFormat:@"%02X%02X%02X", 
(int) (color.redComponent * 0xFF), (int) (color.greenComponent * 0xFF), 
(int) (color.blueComponent * 0xFF)];

8
注意!在所有 NSColor 实例上调用 -redComponent 等并不总是合法的,它们可能会抛出异常。你需要将其转换为 RGB 颜色空间并处理失败情况。你应该参见 Technical Q&A QA1576: How do I get the hexadecimal value of an NSColor object? - Ken Thomases
可以使用 usingColorSpace(:) 方法进行修复。 - Joseph

8

我喜欢D.A.H的解决方案,我将其作为计算属性而不是函数:

import Cocoa

extension NSColor {

    var hexString: String {
        let red = Int(round(self.redComponent * 0xFF))
        let green = Int(round(self.greenComponent * 0xFF))
        let blue = Int(round(self.blueComponent * 0xFF))
        let hexString = NSString(format: "#%02X%02X%02X", red, green, blue)
        return hexString as String
    }

}

请注意,如果NSColor不在RGB颜色空间中,则会引发Objective-C异常 - Duncan的答案可以缓解此问题:https://dev59.com/UnDYa4cB1Zd3GeqPDK8E#51839877 - Alex Rozanski

5

一种不会因颜色空间问题而崩溃的解决方案:

import Cocoa

extension NSColor {

    var hexString: String {
        guard let rgbColor = usingColorSpaceName(NSColorSpaceName.calibratedRGB) else {
            return "#FFFFFF"
        }
        let red = Int(round(rgbColor.redComponent * 0xFF))
        let green = Int(round(rgbColor.greenComponent * 0xFF))
        let blue = Int(round(rgbColor.blueComponent * 0xFF))
        let hexString = NSString(format: "#%02X%02X%02X", red, green, blue)
        return hexString as String
    }
}

颜色空间校正会修改颜色(在我的机器上向黑色方向),从而产生略微错误的十六进制字符串。 - Alex
颜色空间应该是sRGB,因为它用于Web Colors - pointum
@Oskar:usingColorSpaceName已被弃用,在新版本中应该怎么做? - Paul

3

一个选项是创建一个扩展到 NSColor 的扩展。

public extension NSColor {
    func getHexString() -> String {
        let red = Int(round(self.redComponent * 0xFF))
        let grn = Int(round(self.greenComponent * 0xFF))
        let blu = Int(round(self.blueComponent * 0xFF))
        let hexString = NSString(format: "#%02X%02X%02X", red, grn, blu)
        return hexString
    }
}

0

已更新至 Swift 4 版本

extension NSColor {

    var hexString: String {
        guard let rgbColor = usingColorSpaceName(NSColorSpaceName.calibratedRGB) else {
            return "FFFFFF"
        }
        let red = Int(round(rgbColor.redComponent * 0xFF))
        let green = Int(round(rgbColor.greenComponent * 0xFF))
        let blue = Int(round(rgbColor.blueComponent * 0xFF))
        let hexString = NSString(format: "#%02X%02X%02X", red, green, blue)
        return hexString as String
    }

}

usingColorSpaceName已经被弃用,在新版本中应该怎么做? - Paul
@Paul 我认为应该是 usingColorSpace(NSColorSpace. ...) - Sebastian

0

支持灰度色彩:

func toHex(alpha: Bool = false) -> String? {
    if let components = cgColor.components, components.count == 2 {
        let g = Float(components[0])
        let a = Float(components[1])
        if alpha {
            return String(format: "%02lX%02lX%02lX%02lX", lroundf(g * 255), lroundf(g * 255), lroundf(g * 255), lroundf(a * 255))
        } else {
            return String(format: "%02lX%02lX%02lX", lroundf(g * 255), lroundf(g * 255), lroundf(g * 255))
        }
    }
    guard let components = cgColor.components, components.count >= 3 else {
        return nil
    }
    
    let r = Float(components[0])
    let g = Float(components[1])
    let b = Float(components[2])
    var a = Float(1.0)
    
    if components.count >= 4 {
        a = Float(components[3])
    }
    
    if alpha {
        return String(format: "%02lX%02lX%02lX%02lX", lroundf(r * 255), lroundf(g * 255), lroundf(b * 255), lroundf(a * 255))
    } else {
        return String(format: "%02lX%02lX%02lX", lroundf(r * 255), lroundf(g * 255), lroundf(b * 255))
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接