问题
I have an object with a UIColor property:
class Beer: NSObject {
var color: UIColor?
...
}
I'm saving this to a DB, so I need to make this property into a valid JSON type, so I'm thinking of converting it to a string. How can I convert into a string to store, and then when loading using that string to create the UIColor?
回答1:
I have put some sample for both conversion, still you can find many code for the conversion
For the conversion from UIColor to hex string you can use the following code:
extension UIColor {
var rgbComponents:(red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) {
var r:CGFloat = 0
var g:CGFloat = 0
var b:CGFloat = 0
var a:CGFloat = 0
if getRed(&r, green: &g, blue: &b, alpha: &a) {
return (r,g,b,a)
}
return (0,0,0,0)
}
// hue, saturation, brightness and alpha components from UIColor**
var hsbComponents:(hue: CGFloat, saturation: CGFloat, brightness: CGFloat, alpha: CGFloat) {
var hue:CGFloat = 0
var saturation:CGFloat = 0
var brightness:CGFloat = 0
var alpha:CGFloat = 0
if getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha){
return (hue,saturation,brightness,alpha)
}
return (0,0,0,0)
}
var htmlRGBColor:String {
return String(format: "#%02x%02x%02x", Int(rgbComponents.red * 255), Int(rgbComponents.green * 255),Int(rgbComponents.blue * 255))
}
var htmlRGBaColor:String {
return String(format: "#%02x%02x%02x%02x", Int(rgbComponents.red * 255), Int(rgbComponents.green * 255),Int(rgbComponents.blue * 255),Int(rgbComponents.alpha * 255) )
}
}
Sample use:
let myColorBlack = UIColor.blackColor().webColor //#000000ff
let myLghtGrayColor = UIColor.lightGrayColor().webColor //#aaaaaaff
let myDarkGrayColor = UIColor.darkGrayColor().webColor
For more info you can check: https://stackoverflow.com/a/28697136/4557505
https://gist.github.com/yannickl/16f0ed38f0698d9a8ae7
You can store this string inside the db and retrieve it when you need it
From HexString to UIColor
extension UIColor {
public convenience init?(hexString: String) {
let r, g, b, a: CGFloat
if hexString.hasPrefix("#") {
let start = hexString.startIndex.advancedBy(1)
let hexColor = hexString.substringFromIndex(start)
if hexColor.characters.count == 8 {
let scanner = NSScanner(string: hexColor)
var hexNumber: UInt64 = 0
if scanner.scanHexLongLong(&hexNumber) {
r = CGFloat((hexNumber & 0xff000000) >> 24) / 255
g = CGFloat((hexNumber & 0x00ff0000) >> 16) / 255
b = CGFloat((hexNumber & 0x0000ff00) >> 8) / 255
a = CGFloat(hexNumber & 0x000000ff) / 255
self.init(red: r, green: g, blue: b, alpha: a)
return
}
}
}
return nil
}
}
Usage:UIColor(hexString: "#ffe700ff")
Ref: https://www.hackingwithswift.com/example-code/uicolor/how-to-convert-a-hex-color-to-a-uicolor
https://github.com/yeahdongcn/UIColor-Hex-Swift
https://gist.github.com/arshad/de147c42d7b3063ef7bc
回答2:
You can use this function
func returnUIColor(components: String) -> UIColor {
let scanner = Scanner(string: components)
let skipped = CharacterSet(charactersIn: "[], ")
let comma = CharacterSet(charactersIn: ",")
scanner.charactersToBeSkipped = skipped
var r, g, b, a : NSString?
scanner.scanUpToCharacters(from: comma, into: &r)
scanner.scanUpToCharacters(from: comma, into: &g)
scanner.scanUpToCharacters(from: comma, into: &b)
scanner.scanUpToCharacters(from: comma, into: &a)
let defaultColor = UIColor.lightGray
guard let rUnwrapped = r else { return defaultColor }
guard let gUnwrapped = g else { return defaultColor }
guard let bUnwrapped = b else { return defaultColor }
guard let aUnwrapped = a else { return defaultColor }
let rfloat = CGFloat(rUnwrapped.doubleValue)
let gfloat = CGFloat(gUnwrapped.doubleValue)
let bfloat = CGFloat(bUnwrapped.doubleValue)
let afloat = CGFloat(aUnwrapped.doubleValue)
let newUIColor = UIColor(red: rfloat, green: gfloat, blue: bfloat, alpha: afloat)
return newUIColor
}
回答3:
Inspired by @HardikDG code, these are simple Objective C functions:
- (NSString *) colorToString:(UIColor *) color {
CGFloat red, green, blue, alpha;
[color getRed:&red green:&green blue:&blue alpha:&alpha];
return [NSString stringWithFormat:@"%02x%02x%02x", (int)(red * 255), (int)(green * 255) , (int)(blue * 255)];
}
- (UIColor *) stringToColor:(NSString *) color {
if([color length] != 6) {
return nil;
}
NSScanner *scanner = [NSScanner scannerWithString:color];
UInt64 hexNumber = 0;
if ([scanner scanHexLongLong:&hexNumber]) {
CGFloat r = ((hexNumber & 0xff000000) >> 24) / 255.0;
CGFloat g = ((hexNumber & 0x00ff0000) >> 16) / 255.0;
CGFloat b = ((hexNumber & 0x0000ff00) >> 8) / 255.0;
CGFloat a = (hexNumber & 0x000000ff) / 255.0;
return [UIColor colorWithRed:r green:g blue:b alpha:a];
}
return [UIColor whiteColor];
}
回答4:
A little shorter using NSCoding:
public extension UIColor{
var codedString: String?{
do{
let data = try NSKeyedArchiver.archivedData(withRootObject: self, requiringSecureCoding: true)
return data.base64EncodedString()
}
catch let error{
print("Error converting color to coded string: \(error)")
return nil
}
}
static func color(withCodedString string: String) -> UIColor?{
guard let data = Data(base64Encoded: string) else{
return nil
}
return try? NSKeyedUnarchiver.unarchivedObject(ofClass: UIColor.self, from: data)
}
}
回答5:
Swift 3.0 IOS 10.x Don't understand why this is so complicated, this works... I must have missed something... read it carefully, start with item 1 not 0.
// convert color to string
let color = userInfo["color"] as! UIColor
let diyColor = String(describing: color)
// convert string back to color
let diyValues = diyColor.components(separatedBy: " ")
print("diyValues \(diyValues)")
let returnedColor = UIColor(colorLiteralRed: diyValues[1].FloatValue()!, green: diyValues[2].FloatValue()!, blue: diyValues[3].FloatValue()!, alpha: diyValues[4].FloatValue()!)
Using this extension too...
extension String {
func FloatValue() -> Float? {
guard let doubleValue = Double(self) else {
return nil
}
return Float(doubleValue)
}
}
回答6:
Use the below UIColor extension to convert String to Color and vice versa.
extension UIColor {
//Convert RGBA String to UIColor object
//"rgbaString" must be separated by space "0.5 0.6 0.7 1.0" 50% of Red 60% of Green 70% of Blue Alpha 100%
public convenience init?(rgbaString : String){
self.init(ciColor: CIColor(string: rgbaString))
}
//Convert UIColor to RGBA String
func toRGBAString()-> String {
var r: CGFloat = 0
var g: CGFloat = 0
var b: CGFloat = 0
var a: CGFloat = 0
self.getRed(&r, green: &g, blue: &b, alpha: &a)
return "\(r) \(g) \(b) \(a)"
}
//return UIColor from Hexadecimal Color string
public convenience init?(hexaDecimalString: String) {
let r, g, b, a: CGFloat
if hexaDecimalString.hasPrefix("#") {
let start = hexaDecimalString.index(hexaDecimalString.startIndex, offsetBy: 1)
let hexColor = hexaDecimalString.substring(from: start)
if hexColor.characters.count == 8 {
let scanner = Scanner(string: hexColor)
var hexNumber: UInt64 = 0
if scanner.scanHexInt64(&hexNumber) {
r = CGFloat((hexNumber & 0xff000000) >> 24) / 255
g = CGFloat((hexNumber & 0x00ff0000) >> 16) / 255
b = CGFloat((hexNumber & 0x0000ff00) >> 8) / 255
a = CGFloat(hexNumber & 0x000000ff) / 255
self.init(red: r, green: g, blue: b, alpha: a)
return
}
}
}
return nil
}
// Convert UIColor to Hexadecimal String
func toHexString() -> String {
var r: CGFloat = 0
var g: CGFloat = 0
var b: CGFloat = 0
var a: CGFloat = 0
self.getRed(&r, green: &g, blue: &b, alpha: &a)
return String(
format: "%02X%02X%02X",
Int(r * 0xff),
Int(g * 0xff),
Int(b * 0xff)
)
}
}
Save this color string(stringWhite
) in to DataBase
let stringWhite = UIColor.white.toHexString()
when reading color string from DataBase use below code to convert stringWhite
to UIColor
let whiteColor = UIColor(hexaDecimalString: stringWhite)
回答7:
I add my own extension, hope you appreciate:
extension UIColor {
func toRGBAString(uppercased: Bool = true) -> String {
var r: CGFloat = 0
var g: CGFloat = 0
var b: CGFloat = 0
var a: CGFloat = 0
self.getRed(&r, green: &g, blue: &b, alpha: &a)
let rgba = [r, g, b, a].map { $0 * 255 }.reduce("", { $0 + String(format: "%02x", Int($1)) })
return uppercased ? rgba.uppercased() : rgba
}
}
回答8:
Here is an update for:
- Swift 5.0
- combination for UIKit-n-SwiftUI architecture
- #RRGGBBAA / #RRGGBB color values
__
import UIKit
import SwiftUI
extension Color {
init?(hexString: String) {
let rgbaData = getrgbaData(hexString: hexString)
if(rgbaData != nil){
self.init(
.sRGB,
red: Double(rgbaData!.r),
green: Double(rgbaData!.g),
blue: Double(rgbaData!.b),
opacity: Double(rgbaData!.a)
)
return
}
return nil
}
}
extension UIColor {
public convenience init?(hexString: String) {
let rgbaData = getrgbaData(hexString: hexString)
if(rgbaData != nil){
self.init(
red: rgbaData!.r,
green: rgbaData!.g,
blue: rgbaData!.b,
alpha: rgbaData!.a)
return
}
return nil
}
}
private func getrgbaData(hexString: String) -> (r: CGFloat, g: CGFloat, b: CGFloat, a: CGFloat)? {
var rgbaData : (r: CGFloat, g: CGFloat, b: CGFloat, a: CGFloat)? = nil
if hexString.hasPrefix("#") {
let start = hexString.index(hexString.startIndex, offsetBy: 1)
let hexColor = String(hexString[start...]) // Swift 4
let scanner = Scanner(string: hexColor)
var hexNumber: UInt64 = 0
if scanner.scanHexInt64(&hexNumber) {
rgbaData = { // start of a closure expression that returns a Vehicle
switch hexColor.count {
case 8:
return ( r: CGFloat((hexNumber & 0xff000000) >> 24) / 255,
g: CGFloat((hexNumber & 0x00ff0000) >> 16) / 255,
b: CGFloat((hexNumber & 0x0000ff00) >> 8) / 255,
a: CGFloat( hexNumber & 0x000000ff) / 255
)
case 6:
return ( r: CGFloat((hexNumber & 0xff0000) >> 16) / 255,
g: CGFloat((hexNumber & 0x00ff00) >> 8) / 255,
b: CGFloat((hexNumber & 0x0000ff)) / 255,
a: 1.0
)
default:
return nil
}
}()
}
}
return rgbaData
}
来源:https://stackoverflow.com/questions/36341358/how-to-convert-uicolor-to-string-and-string-to-uicolor-using-swift