这是一个Swift 5的解决方案,作为UIColor的扩展,将UIColor对象转换为RGB(#RRGGBB)格式或RGBA(#RRGGBBAA)格式的十六进制颜色字符串,并且还可以使用任一格式创建UIColor,提供alpha参数选项,以#RRGGBB形式作为非默认值1.0的alpha。
我从@boidkan的答案开始,然后在S.O.上搜索其他解决方案,然后对它们进行了优化和改进,得到了一个我可以接受的解决方案,并在playground中进行了测试。
var hexRGB : String {
func comp(_ value: CGFloat, _ byteShift: Int = 0) -> Int { return Int(value * 0xff) << (byteShift * 8) }
var r = CGFloat(0), b = CGFloat(0), g = CGFloat(0), a = CGFloat(0)
getRed(&r, green: &g, blue: &b, alpha: &a)
return String(format: "#%6.6X", comp(r, 2) | comp(g, 1) | comp(b))
}
var hexRGBA : String {
func comp(_ value: CGFloat, _ byteShift: Int = 0) -> Int { return Int(value * 0xff) << (byteShift * 8) }
var r = CGFloat(0), b = CGFloat(0), g = CGFloat(0), a = CGFloat(0)
getRed(&r, green: &g, blue: &b, alpha: &a)
return String(format: "#%8.8X", comp(r, 3) | comp(g, 2) | comp(b, 1) | comp(a))
}
convenience init(hexRGBA: String, alpha: CGFloat = 1.0) {
let cleanHex = hexRGBA.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
.replacingOccurrences(of: #"[^0-9a-fA-F]"#, with: "", options: .regularExpression)
assert(cleanHex.count == 6 || cleanHex.count == 8, "Bad RGB/RGBA value")
var rgbIntValue: UInt64 = 0
Scanner(string:cleanHex).scanHexInt64(&rgbIntValue)
let hh1 = CGFloat( Double((rgbIntValue & 0xff000000) >> 24) / 255.0)
let hh2 = CGFloat( Double((rgbIntValue & 0x00ff0000) >> 16) / 255.0)
let hh3 = CGFloat( Double((rgbIntValue & 0x0000ff00) >> 8) / 255.0)
let hh4 = CGFloat( Double((rgbIntValue & 0x000000ff) / 255.0)
if (cleanHex.count == 8) {
self.init(red: hh1, green: hh2, blue: hh3, alpha: hh4)
return
}
self.init(red: hh2, green: hh3, blue: hh4, alpha: alpha)
}