I’ve found that defining a custom UIColor using RGB values is a little counter intuitive compared to the more common hexadecimal notation used in CSS. This is particularly true if you want to define a color value in a file and don’t want to have to split it into three separate values.
For the most part, NSScanner has everything we need to parse data types (int, float, string etc) from a string.
The following is a simple method that will convert a hexadecimal color (e.g. #FFCC88) into an equivalent UIColor object.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | - (UIColor *) colorForHex:(NSString *)hexColor { hexColor = [[hexColor stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet] ] uppercaseString]; // String should be 6 or 7 characters if it includes '#' if ([hexColor length] < 6) return [UIColor blackColor]; // strip # if it appears if ([hexColor hasPrefix:@"#"]) hexColor = [cString substringFromIndex:1]; // if the value isn't 6 characters at this point return // the color black if ([hexColor length] != 6) return [UIColor blackColor]; // Separate into r, g, b substrings NSRange range; range.location = 0; range.length = 2; NSString *rString = [hexColor substringWithRange:range]; range.location = 2; NSString *gString = [hexColor substringWithRange:range]; range.location = 4; NSString *bString = [hexColor substringWithRange:range]; // Scan values unsigned int r, g, b; [[NSScanner scannerWithString:rString] scanHexInt:&r]; [[NSScanner scannerWithString:gString] scanHexInt:&g]; [[NSScanner scannerWithString:bString] scanHexInt:&b]; return [UIColor colorWithRed:((float) r / 255.0f) green:((float) g / 255.0f) blue:((float) b / 255.0f) alpha:1.0f]; } |
Notice that I had to first separate our the hex values for the red, green, and blue components first as substrings and then apply the NSScanner to those substrings.
Rodney,
That’s interesting, but I believe there’s an easier way to provide the same thing with a macro. I blogged about this a few months ago:
http://pessoal.org/blog/2008/11/27/creating-uicolor-objects-from-hex-values/
Hope that’s useful!
–Joao
Rodney,
Thanks, this is very helpful.
Cheers,
Ivan
@Joao Prado Maia
Thanks for that tip … it is much more concise. Unfortunately it doesn’t deal with the issue that I was solving. In my case, the hex value was stored in a text file as a string. This file was something that was created by an entirely different application (thus no control over format). Given that the rgbvalue was a string, NSScanner made the most sense. All that said, I will definitely use your approach if I have a hex value in an integer value.
Also note that the UIColor convenience constructor used above interprets the RGBA values in the device colorspace. This differs from the hex strings in CSS which are in sRGB.
To use sRGB it looks like one has to go via CGColor.
Ok, so I should have finished coding before replying here. It seems that the iPhone doesn’t support sRGB when going via CGColor: kCGColorSpaceSRGB is unavailable.
Thank you. This was useful and well presented.
This is good. Should you want something even more complex have a look at this: http://paste.lisp.org/display/74985
This is my technique:
#define HEXCOLOR(c) [UIColor colorWithRed:((c)&0xFF)/255.0 \
green:((c>>8)&0xFF)/255.0 \
blue:((c>>16)&0xFF)/255.0 \
alpha:((c>>24)&0xFF)/255.0]
unsigned int colorValue;
[[NSScanner scannerWithString:colorString] scanHexInt:&colorValue];
UIColor *color = HEXCOLOR(colorValue);
A sample hex color string “7fcf0064” that should come out as light purple. “64” is red and “7f” is alpha.
Thanks for sharing this. Its a nice compact way of doing the stuff
Here’s an open source UIColor category / extension to make hex color creation from NSString possible:
http://github.com/jonasschnelli/UIColor-i7HexColor
Thanks, this is very useful.
This works quite well. Thanks.