{"id":486,"date":"2012-06-23T00:56:15","date_gmt":"2012-06-23T05:56:15","guid":{"rendered":"http:\/\/www.juggleware.com\/blog\/?p=486"},"modified":"2012-06-23T09:06:28","modified_gmt":"2012-06-23T14:06:28","slug":"uicolor-expanded","status":"publish","type":"post","link":"https:\/\/www.juggleware.com\/blog\/2012\/06\/uicolor-expanded\/","title":{"rendered":"UIColor-expanded"},"content":{"rendered":"<p>Here&#8217;s some handy code to extend UIColor, based largely on code by Erica Sadun, but with a couple of fixes and handy (to me) additions. Let me know if this is useful&#8230;<br \/>\n<!--more--><br \/>\n<code>\/\/<br \/>\n\/\/  UIColor-Expanded.h<br \/>\n\/\/<br \/>\n\/\/based on code from Erica Sadun at http:\/\/arstechnica.com\/apple\/guides\/2009\/02\/iphone-development-accessing-uicolor-components.ars<br \/>\n\/\/ latest code from http:\/\/github.com\/ars\/uicolor-utilities<\/p>\n<p>#import <UIKit\/UIKit.h><\/p>\n<p>#define SUPPORTS_UNDOCUMENTED_API\t0<\/p>\n<p>@interface UIColor (UIColor_Expanded)<br \/>\n@property (nonatomic, readonly) CGColorSpaceModel colorSpaceModel;<br \/>\n@property (nonatomic, readonly) BOOL canProvideRGBComponents;<br \/>\n@property (nonatomic, readonly) CGFloat red; \/\/ Only valid if canProvideRGBComponents is YES<br \/>\n@property (nonatomic, readonly) CGFloat green; \/\/ Only valid if canProvideRGBComponents is YES<br \/>\n@property (nonatomic, readonly) CGFloat blue; \/\/ Only valid if canProvideRGBComponents is YES<br \/>\n@property (nonatomic, readonly) CGFloat white; \/\/ Only valid if colorSpaceModel == kCGColorSpaceModelMonochrome<br \/>\n@property (nonatomic, readonly) CGFloat alpha;<br \/>\n@property (nonatomic, readonly) UInt32 rgbHex;<\/p>\n<p>- (NSString *)colorSpaceString;<\/p>\n<p>- (NSArray *)arrayFromRGBAComponents;<\/p>\n<p>- (BOOL)red:(CGFloat *)r green:(CGFloat *)g blue:(CGFloat *)b alpha:(CGFloat *)a;<\/p>\n<p>- (UIColor *)colorByLuminanceMapping;<\/p>\n<p>- (UIColor *)colorByMultiplyingByRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha;<br \/>\n- (UIColor *)       colorByAddingRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha;<br \/>\n- (UIColor *) colorByLighteningToRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha;<br \/>\n- (UIColor *)  colorByDarkeningToRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha;<\/p>\n<p>- (UIColor *)colorByMultiplyingBy:(CGFloat)f;<br \/>\n- (UIColor *)       colorByAdding:(CGFloat)f;<br \/>\n- (UIColor *) colorByLighteningTo:(CGFloat)f;<br \/>\n- (UIColor *)  colorByDarkeningTo:(CGFloat)f;<\/p>\n<p>- (UIColor *)colorByMultiplyingByColor:(UIColor *)color;<br \/>\n- (UIColor *)       colorByAddingColor:(UIColor *)color;<br \/>\n- (UIColor *) colorByLighteningToColor:(UIColor *)color;<br \/>\n- (UIColor *)  colorByDarkeningToColor:(UIColor *)color;<\/p>\n<p>\/\/added by Alec 2010-09-16<br \/>\n- (UIColor *) colorByMixingWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha;<br \/>\n- (UIColor *) colorByMixingWithColor:(UIColor *)color;<\/p>\n<p>- (NSString *)stringFromColor;<br \/>\n- (NSString *)hexStringFromColor;<\/p>\n<p>+ (UIColor *)randomColor;<br \/>\n+ (UIColor *)colorWithString:(NSString *)stringToConvert;<br \/>\n+ (UIColor *)colorWithRGBHex:(UInt32)hex;<br \/>\n+ (UIColor *)colorWithHexString:(NSString *)stringToConvert;<\/p>\n<p>+ (UIColor *)colorWithName:(NSString *)cssColorName;<br \/>\n+(UIColor *)colorBetweenColor:(UIColor *)color1 andColor:(UIColor *)color2 onSpectrumAt:(CGFloat)position;<\/p>\n<p>@end<\/p>\n<p>#if SUPPORTS_UNDOCUMENTED_API<br \/>\n\/\/ UIColor_Undocumented_Expanded<br \/>\n\/\/ Methods which rely on undocumented methods of UIColor<br \/>\n@interface UIColor (UIColor_Undocumented_Expanded)<br \/>\n- (NSString *)fetchStyleString;<br \/>\n- (UIColor *)rgbColor; \/\/ Via Poltras<br \/>\n@end<br \/>\n#endif \/\/ SUPPORTS_UNDOCUMENTED_API<\/p>\n<p>\/\/<br \/>\n\/\/  UIColor-Expanded.m<br \/>\n\/\/<\/p>\n<p>#import \"UIColor-Expanded.h\"<\/p>\n<p>\/*<br \/>\n FOR REFERENCE: Color Space Models: enum CGColorSpaceModel {<br \/>\n kCGColorSpaceModelUnknown = -1,<br \/>\n kCGColorSpaceModelMonochrome,<br \/>\n kCGColorSpaceModelRGB,<br \/>\n kCGColorSpaceModelCMYK,<br \/>\n kCGColorSpaceModelLab,<br \/>\n kCGColorSpaceModelDeviceN,<br \/>\n kCGColorSpaceModelIndexed,<br \/>\n kCGColorSpaceModelPattern<br \/>\n };<br \/>\n *\/<\/p>\n<p>\/\/ Static cache of looked up color names. Used with +colorWithName:<br \/>\nstatic NSMutableDictionary *colorNameCache = nil;<\/p>\n<p>#if SUPPORTS_UNDOCUMENTED_API<br \/>\n\/\/ UIColor_Undocumented<br \/>\n\/\/ Undocumented methods of UIColor<br \/>\n@interface UIColor (UIColor_Undocumented)<br \/>\n- (NSString *)styleString;<br \/>\n@end<br \/>\n#endif \/\/ SUPPORTS_UNDOCUMENTED_API<\/p>\n<p>@interface UIColor (UIColor_Expanded_Support)<br \/>\n+ (UIColor *)searchForColorByName:(NSString *)cssColorName;<br \/>\n@end<\/p>\n<p>#pragma mark -<\/p>\n<p>@implementation UIColor (UIColor_Expanded)<\/p>\n<p>- (CGColorSpaceModel)colorSpaceModel {<br \/>\n\treturn CGColorSpaceGetModel(CGColorGetColorSpace(self.CGColor));<br \/>\n}<\/p>\n<p>- (NSString *)colorSpaceString {<br \/>\n\tswitch (self.colorSpaceModel) {<br \/>\n\t\tcase kCGColorSpaceModelUnknown:<br \/>\n\t\t\treturn @\"kCGColorSpaceModelUnknown\";<br \/>\n\t\tcase kCGColorSpaceModelMonochrome:<br \/>\n\t\t\treturn @\"kCGColorSpaceModelMonochrome\";<br \/>\n\t\tcase kCGColorSpaceModelRGB:<br \/>\n\t\t\treturn @\"kCGColorSpaceModelRGB\";<br \/>\n\t\tcase kCGColorSpaceModelCMYK:<br \/>\n\t\t\treturn @\"kCGColorSpaceModelCMYK\";<br \/>\n\t\tcase kCGColorSpaceModelLab:<br \/>\n\t\t\treturn @\"kCGColorSpaceModelLab\";<br \/>\n\t\tcase kCGColorSpaceModelDeviceN:<br \/>\n\t\t\treturn @\"kCGColorSpaceModelDeviceN\";<br \/>\n\t\tcase kCGColorSpaceModelIndexed:<br \/>\n\t\t\treturn @\"kCGColorSpaceModelIndexed\";<br \/>\n\t\tcase kCGColorSpaceModelPattern:<br \/>\n\t\t\treturn @\"kCGColorSpaceModelPattern\";<br \/>\n\t\tdefault:<br \/>\n\t\t\treturn @\"Not a valid color space\";<br \/>\n\t}<br \/>\n}<\/p>\n<p>- (BOOL)canProvideRGBComponents {<br \/>\n\tswitch (self.colorSpaceModel) {<br \/>\n\t\tcase kCGColorSpaceModelRGB:<br \/>\n\t\tcase kCGColorSpaceModelMonochrome:<br \/>\n\t\t\treturn YES;<br \/>\n\t\tdefault:<br \/>\n\t\t\treturn NO;<br \/>\n\t}<br \/>\n}<\/p>\n<p>- (NSArray *)arrayFromRGBAComponents {<br \/>\n\tNSAssert(self.canProvideRGBComponents, @\"Must be an RGB color to use -arrayFromRGBAComponents\");<\/p>\n<p>\tCGFloat r,g,b,a;<br \/>\n\tif (![self red:&r green:&g blue:&b alpha:&a]) return nil;<\/p>\n<p>\treturn [NSArray arrayWithObjects:<br \/>\n\t\t\t[NSNumber numberWithFloat:r],<br \/>\n\t\t\t[NSNumber numberWithFloat:g],<br \/>\n\t\t\t[NSNumber numberWithFloat:b],<br \/>\n\t\t\t[NSNumber numberWithFloat:a],<br \/>\n\t\t\tnil];<br \/>\n}<\/p>\n<p>- (BOOL)red:(CGFloat *)red green:(CGFloat *)green blue:(CGFloat *)blue alpha:(CGFloat *)alpha {<br \/>\n\tconst CGFloat *components = CGColorGetComponents(self.CGColor);<\/p>\n<p>\tCGFloat r,g,b,a;<\/p>\n<p>\tswitch (self.colorSpaceModel) {<br \/>\n\t\tcase kCGColorSpaceModelMonochrome:<br \/>\n\t\t\tr = g = b = components[0];<br \/>\n\t\t\ta = components[1];<br \/>\n\t\t\tbreak;<br \/>\n\t\tcase kCGColorSpaceModelRGB:<br \/>\n\t\t\tr = components[0];<br \/>\n\t\t\tg = components[1];<br \/>\n\t\t\tb = components[2];<br \/>\n\t\t\ta = components[3];<br \/>\n\t\t\tbreak;<br \/>\n\t\tdefault:\t\/\/ We don't know how to handle this model<br \/>\n\t\t\treturn NO;<br \/>\n\t}<\/p>\n<p>\tif (red) *red = r;<br \/>\n\tif (green) *green = g;<br \/>\n\tif (blue) *blue = b;<br \/>\n\tif (alpha) *alpha = a;<\/p>\n<p>\treturn YES;<br \/>\n}<\/p>\n<p>- (CGFloat)red {<br \/>\n\tNSAssert(self.canProvideRGBComponents, @\"Must be an RGB color to use -red\");<br \/>\n\tconst CGFloat *c = CGColorGetComponents(self.CGColor);<br \/>\n\treturn c[0];<br \/>\n}<\/p>\n<p>- (CGFloat)green {<br \/>\n\tNSAssert(self.canProvideRGBComponents, @\"Must be an RGB color to use -green\");<br \/>\n\tconst CGFloat *c = CGColorGetComponents(self.CGColor);<br \/>\n\tif (self.colorSpaceModel == kCGColorSpaceModelMonochrome) return c[0];<br \/>\n\treturn c[1];<br \/>\n}<\/p>\n<p>- (CGFloat)blue {<br \/>\n\tNSAssert(self.canProvideRGBComponents, @\"Must be an RGB color to use -blue\");<br \/>\n\tconst CGFloat *c = CGColorGetComponents(self.CGColor);<br \/>\n\tif (self.colorSpaceModel == kCGColorSpaceModelMonochrome) return c[0];<br \/>\n\treturn c[2];<br \/>\n}<\/p>\n<p>- (CGFloat)white {<br \/>\n\tNSAssert(self.colorSpaceModel == kCGColorSpaceModelMonochrome, @\"Must be a Monochrome color to use -white\");<br \/>\n\tconst CGFloat *c = CGColorGetComponents(self.CGColor);<br \/>\n\treturn c[0];<br \/>\n}<\/p>\n<p>- (CGFloat)alpha {<br \/>\n\treturn CGColorGetAlpha(self.CGColor);<br \/>\n}<\/p>\n<p>- (UInt32)rgbHex {<br \/>\n\tNSAssert(self.canProvideRGBComponents, @\"Must be a RGB color to use rgbHex\");<\/p>\n<p>\tCGFloat r,g,b,a;<br \/>\n\tif (![self red:&r green:&g blue:&b alpha:&a]) return 0;<\/p>\n<p>\tr = MIN(MAX(self.red, 0.0f), 1.0f);<br \/>\n\tg = MIN(MAX(self.green, 0.0f), 1.0f);<br \/>\n\tb = MIN(MAX(self.blue, 0.0f), 1.0f);<\/p>\n<p>\treturn (((int)roundf(r * 255)) << 16)\n\t| (((int)roundf(g * 255)) << 8)\n\t| (((int)roundf(b * 255)));\n}\n\n#pragma mark Arithmetic operations\n\n- (UIColor *)colorByLuminanceMapping {\n\tNSAssert(self.canProvideRGBComponents, @\"Must be a RGB color to use arithmatic operations\");\n\t\n\tCGFloat r,g,b,a;\n\tif (![self red:&#038;r green:&#038;g blue:&#038;b alpha:&#038;a]) return nil;\n\t\n\t\/\/ http:\/\/en.wikipedia.org\/wiki\/Luma_(video)\n\t\/\/ Y = 0.2126 R + 0.7152 G + 0.0722 B\n\treturn [UIColor colorWithWhite:r*0.2126f + g*0.7152f + b*0.0722f\n\t\t\t\t\t\t\t alpha:a];\n\t\n}\n\n- (UIColor *)colorByMultiplyingByRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha {\n\tNSAssert(self.canProvideRGBComponents, @\"Must be a RGB color to use arithmatic operations\");\n\t\n\tCGFloat r,g,b,a;\n\tif (![self red:&#038;r green:&#038;g blue:&#038;b alpha:&#038;a]) return nil;\n\t\n\treturn [UIColor colorWithRed:MAX(0.0, MIN(1.0, r * red))\n\t\t\t\t\t\t   green:MAX(0.0, MIN(1.0, g * green)) \n\t\t\t\t\t\t\tblue:MAX(0.0, MIN(1.0, b * blue))\n\t\t\t\t\t\t   alpha:MAX(0.0, MIN(1.0, a * alpha))];\n}\n\n- (UIColor *)colorByAddingRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha {\n\tNSAssert(self.canProvideRGBComponents, @\"Must be a RGB color to use arithmatic operations\");\n\t\n\tCGFloat r,g,b,a;\n\tif (![self red:&#038;r green:&#038;g blue:&#038;b alpha:&#038;a]) return nil;\n\t\n\treturn [UIColor colorWithRed:MAX(0.0, MIN(1.0, r + red))\n\t\t\t\t\t\t   green:MAX(0.0, MIN(1.0, g + green)) \n\t\t\t\t\t\t\tblue:MAX(0.0, MIN(1.0, b + blue))\n\t\t\t\t\t\t   alpha:MAX(0.0, MIN(1.0, a + alpha))];\n}\n\n- (UIColor *)colorByLighteningToRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha {\n\tNSAssert(self.canProvideRGBComponents, @\"Must be a RGB color to use arithmatic operations\");\n\t\n\tCGFloat r,g,b,a;\n\tif (![self red:&#038;r green:&#038;g blue:&#038;b alpha:&#038;a]) return nil;\n\t\n\treturn [UIColor colorWithRed:MAX(r, red)\n\t\t\t\t\t\t   green:MAX(g, green)\n\t\t\t\t\t\t\tblue:MAX(b, blue)\n\t\t\t\t\t\t   alpha:MAX(a, alpha)];\n}\n\n- (UIColor *)colorByDarkeningToRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha {\n\tNSAssert(self.canProvideRGBComponents, @\"Must be a RGB color to use arithmatic operations\");\n\t\n\tCGFloat r,g,b,a;\n\tif (![self red:&#038;r green:&#038;g blue:&#038;b alpha:&#038;a]) return nil;\n\t\n\treturn [UIColor colorWithRed:MIN(r, red)\n\t\t\t\t\t\t   green:MIN(g, green)\n\t\t\t\t\t\t\tblue:MIN(b, blue)\n\t\t\t\t\t\t   alpha:MIN(a, alpha)];\n}\n\n- (UIColor *)colorByMultiplyingBy:(CGFloat)f {\n\treturn [self colorByMultiplyingByRed:f green:f blue:f alpha:1.0f];\n}\n\n- (UIColor *)colorByAdding:(CGFloat)f {\n\treturn [self colorByAddingRed:f green:f blue:f alpha:1.0f];\n}\n\n- (UIColor *)colorByLighteningTo:(CGFloat)f {\n\treturn [self colorByLighteningToRed:f green:f blue:f alpha:0.0f];\n}\n\n- (UIColor *)colorByDarkeningTo:(CGFloat)f {\n\treturn [self colorByDarkeningToRed:f green:f blue:f alpha:1.0f];\n}\n\n- (UIColor *)colorByMultiplyingByColor:(UIColor *)color {\n\tNSAssert(self.canProvideRGBComponents, @\"Must be a RGB color to use arithmatic operations\");\n\t\n\tCGFloat r,g,b,a;\n\tif (![self red:&#038;r green:&#038;g blue:&#038;b alpha:&#038;a]) return nil;\n\t\n\treturn [color colorByMultiplyingByRed:r green:g blue:b alpha:1.0f];\n}\n\n- (UIColor *)colorByAddingColor:(UIColor *)color {\n\tNSAssert(self.canProvideRGBComponents, @\"Must be a RGB color to use arithmatic operations\");\n\t\n\tCGFloat r,g,b,a;\n\tif (![self red:&#038;r green:&#038;g blue:&#038;b alpha:&#038;a]) return nil;\n\t\n\treturn [color colorByAddingRed:r green:g blue:b alpha:0.0f];\n}\n\n- (UIColor *)colorByLighteningToColor:(UIColor *)color {\n\tNSAssert(self.canProvideRGBComponents, @\"Must be a RGB color to use arithmatic operations\");\n\t\n\tCGFloat r,g,b,a;\n\tif (![self red:&#038;r green:&#038;g blue:&#038;b alpha:&#038;a]) return nil;\n\t\n\treturn [color colorByLighteningToRed:r green:g blue:b alpha:0.0f];\n}\n\n- (UIColor *)colorByDarkeningToColor:(UIColor *)color {\n\tNSAssert(self.canProvideRGBComponents, @\"Must be a RGB color to use arithmatic operations\");\n\t\n\tCGFloat r,g,b,a;\n\tif (![self red:&#038;r green:&#038;g blue:&#038;b alpha:&#038;a]) return nil;\n\t\n\treturn [color colorByDarkeningToRed:r green:g blue:b alpha:1.0f];\n}\n\n\/\/added by Alec 2010-09-16\n- (UIColor *) colorByMixingWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha{\n\tNSAssert(self.canProvideRGBComponents, @\"Must be a RGB color to use arithmatic operations\");\n\t\n\tCGFloat r,g,b,a;\n\tif (![self red:&#038;r green:&#038;g blue:&#038;b alpha:&#038;a]) return nil;\n\t\n\treturn [UIColor colorWithRed:(r+red)\/2.0\n\t\t\t\t\t\t   green:(g+green)\/2.0\n\t\t\t\t\t\t\tblue:(b+blue)\/2.0\n\t\t\t\t\t\t   alpha:(a+alpha)\/2.0];\n\t\n}\n- (UIColor *) colorByMixingWithColor:(UIColor *)color{\n\tNSAssert(self.canProvideRGBComponents, @\"Must be a RGB color to use arithmatic operations\");\n\t\n\tCGFloat r,g,b,a;\n\tif (![self red:&#038;r green:&#038;g blue:&#038;b alpha:&#038;a]) return nil;\n\treturn [color colorByMixingWithRed:r green:g blue:b alpha:a];\n}\n\n\n\n\n#pragma mark String utilities\n\n- (NSString *)stringFromColor {\n\tNSAssert(self.canProvideRGBComponents, @\"Must be an RGB color to use -stringFromColor\");\n\tNSString *result;\n\tswitch (self.colorSpaceModel) {\n\t\tcase kCGColorSpaceModelRGB:\n\t\t\tresult = [NSString stringWithFormat:@\"{%0.3f, %0.3f, %0.3f, %0.3f}\", self.red, self.green, self.blue, self.alpha];\n\t\t\tbreak;\n\t\tcase kCGColorSpaceModelMonochrome:\n\t\t\tresult = [NSString stringWithFormat:@\"{%0.3f, %0.3f}\", self.white, self.alpha];\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tresult = nil;\n\t}\n\treturn result;\n}\n\n- (NSString *)hexStringFromColor {\n\treturn [NSString stringWithFormat:@\"%0.6X\", self.rgbHex];\n}\n\n+ (UIColor *)colorWithString:(NSString *)stringToConvert {\n\tNSScanner *scanner = [NSScanner scannerWithString:stringToConvert];\n\tif (![scanner scanString:@\"{\" intoString:NULL]) return nil;\n\tconst NSUInteger kMaxComponents = 4;\n\tCGFloat c[kMaxComponents];\n\tNSUInteger i = 0;\n\tif (![scanner scanFloat:&#038;c[i++]]) return nil;\n\twhile (1) {\n\t\tif ([scanner scanString:@\"}\" intoString:NULL]) break;\n\t\tif (i >= kMaxComponents) return nil;<br \/>\n\t\tif ([scanner scanString:@\",\" intoString:NULL]) {<br \/>\n\t\t\tif (![scanner scanFloat:&c[i++]]) return nil;<br \/>\n\t\t} else {<br \/>\n\t\t\t\/\/ either we're at the end of there's an unexpected character here<br \/>\n\t\t\t\/\/ both cases are error conditions<br \/>\n\t\t\treturn nil;<br \/>\n\t\t}<br \/>\n\t}<br \/>\n\tif (![scanner isAtEnd]) return nil;<br \/>\n\tUIColor *color;<br \/>\n\tswitch (i) {<br \/>\n\t\tcase 2: \/\/ monochrome<br \/>\n\t\t\tcolor = [UIColor colorWithWhite:c[0] alpha:c[1]];<br \/>\n\t\t\tbreak;<br \/>\n\t\tcase 4: \/\/ RGB<br \/>\n\t\t\tcolor = [UIColor colorWithRed:c[0] green:c[1] blue:c[2] alpha:c[3]];<br \/>\n\t\t\tbreak;<br \/>\n\t\tdefault:<br \/>\n\t\t\tcolor = nil;<br \/>\n\t}<br \/>\n\treturn color;<br \/>\n}<\/p>\n<p>#pragma mark Class methods<\/p>\n<p>+ (UIColor *)randomColor {<br \/>\n\treturn [UIColor colorWithRed:(CGFloat)RAND_MAX \/ random()<br \/>\n\t\t\t\t\t\t   green:(CGFloat)RAND_MAX \/ random()<br \/>\n\t\t\t\t\t\t\tblue:(CGFloat)RAND_MAX \/ random()<br \/>\n\t\t\t\t\t\t   alpha:1.0f];<br \/>\n}<\/p>\n<p>+ (UIColor *)colorWithRGBHex:(UInt32)hex {<br \/>\n\tint r = (hex >> 16) & 0xFF;<br \/>\n\tint g = (hex >> 8) & 0xFF;<br \/>\n\tint b = (hex) & 0xFF;<\/p>\n<p>\treturn [UIColor colorWithRed:r \/ 255.0f<br \/>\n\t\t\t\t\t\t   green:g \/ 255.0f<br \/>\n\t\t\t\t\t\t\tblue:b \/ 255.0f<br \/>\n\t\t\t\t\t\t   alpha:1.0f];<br \/>\n}<\/p>\n<p>\/\/ Returns a UIColor by scanning the string for a hex number and passing that to +[UIColor colorWithRGBHex:]<br \/>\n\/\/ Skips any leading whitespace and ignores any trailing characters<br \/>\n+ (UIColor *)colorWithHexString:(NSString *)stringToConvert {<br \/>\n\tNSScanner *scanner = [NSScanner scannerWithString:stringToConvert];<br \/>\n\tunsigned hexNum;<br \/>\n\tif (![scanner scanHexInt:&hexNum]) return nil;<br \/>\n\treturn [UIColor colorWithRGBHex:hexNum];<br \/>\n}<\/p>\n<p>\/\/ Lookup a color using css 3\/svg color name<br \/>\n+ (UIColor *)colorWithName:(NSString *)cssColorName {<br \/>\n\tUIColor *color;<br \/>\n\t@synchronized(colorNameCache) {<br \/>\n\t\t\/\/ Look for the color in the cache<br \/>\n\t\tcolor = [colorNameCache objectForKey:cssColorName];<\/p>\n<p>\t\tif ((id)color == [NSNull null]) {<br \/>\n\t\t\t\/\/ If it wasn't there previously, it's still not there now<br \/>\n\t\t\tcolor = nil;<br \/>\n\t\t} else if (!color) {<br \/>\n\t\t\t\/\/ Color not in cache, so search for it now<br \/>\n\t\t\tcolor = [self searchForColorByName:cssColorName];<\/p>\n<p>\t\t\t\/\/ Set the value in cache, storing NSNull on failure<br \/>\n\t\t\t[colorNameCache setObject:(color ?: (id)[NSNull null])<br \/>\n\t\t\t\t\t\t\t   forKey:cssColorName];<br \/>\n\t\t}<br \/>\n\t}<\/p>\n<p>\treturn color;<br \/>\n}<\/p>\n<p>+(UIColor *)colorBetweenColor:(UIColor *)color1 andColor:(UIColor *)color2 onSpectrumAt:(CGFloat)position{<\/p>\n<p>    CGFloat r,g,b,a;<br \/>\n    CGFloat r1,g1,b1,a1;<br \/>\n    CGFloat r2,g2,b2,a2;<\/p>\n<p>    NSAssert(color1.canProvideRGBComponents, @\"Must be a RGB color to use arithmatic operations\");<\/p>\n<p>    NSAssert(color2.canProvideRGBComponents, @\"Must be a RGB color to use arithmatic operations\");<\/p>\n<p>    NSAssert((position>=0)&&(position<=1.0), @\"Position must be between 0.0 and 1.0\");\n\n    \n\tif (![color1 red:&#038;r1 green:&#038;g1 blue:&#038;b1 alpha:&#038;a1]) return nil;\n\tif (![color2 red:&#038;r2 green:&#038;g2 blue:&#038;b2 alpha:&#038;a2]) return nil;\n\n    r = r1 * (1.0-position) + r2 * position;\n    g = g1 * (1.0-position) + g2 * position;\n    b = b1 * (1.0-position) + b2 * position;\n    a = a1 * (1.0-position) + a2 * position;\n\n    \n    UIColor *color = [UIColor colorWithRed:r green:g blue:b alpha:a];\n    \n    \n    \n    return color;\n    \n}\n\n#pragma mark UIColor_Expanded initialization\n\n+ (void)load {\n\tcolorNameCache = [[NSMutableDictionary alloc] init];\n}\n\n@end\n\n#pragma mark -\n\n#if SUPPORTS_UNDOCUMENTED_API\n@implementation UIColor (UIColor_Undocumented_Expanded)\n- (NSString *)fetchStyleString {\n\treturn [self styleString];\n}\n\n\/\/ Convert a color into RGB Color space, courtesy of Poltras\n\/\/ via http:\/\/ofcodeandmen.poltras.com\/2009\/01\/22\/convert-a-cgcolorref-to-another-cgcolorspaceref\/\n\/\/\n- (UIColor *)rgbColor {\n\t\/\/ Call to undocumented method \"styleString\".\n\tNSString *style = [self styleString];\n\tNSScanner *scanner = [NSScanner scannerWithString:style];\n\tCGFloat red, green, blue;\n\tif (![scanner scanString:@\"rgb(\" intoString:NULL]) return nil;\n\tif (![scanner scanFloat:&#038;red]) return nil;\n\tif (![scanner scanString:@\",\" intoString:NULL]) return nil;\n\tif (![scanner scanFloat:&#038;green]) return nil;\n\tif (![scanner scanString:@\",\" intoString:NULL]) return nil;\n\tif (![scanner scanFloat:&#038;blue]) return nil;\n\tif (![scanner scanString:@\")\" intoString:NULL]) return nil;\n\tif (![scanner isAtEnd]) return nil;\n\t\n\treturn [UIColor colorWithRed:red green:green blue:blue alpha:self.alpha];\n}\n@end\n#endif \/\/ SUPPORTS_UNDOCUMENTED_API\n\n@implementation UIColor (UIColor_Expanded_Support)\n\/*\n * Database of color names and hex rgb values, derived\n * from the css 3 color spec:\n *\thttp:\/\/www.w3.org\/TR\/css3-color\/\n *\n * We think this is a very compact way of storing\n * this information, and relatively cheap to lookup.\n *\n * Note that we search for color names starting with ','\n * and terminated by '#', so that we don't get false matches.\n * For this reason, the database begins with ','.\n *\/\nstatic const char *colorNameDB = \",\"\n\"aliceblue#f0f8ff,antiquewhite#faebd7,aqua#00ffff,aquamarine#7fffd4,azure#f0ffff,\"\n\"beige#f5f5dc,bisque#ffe4c4,black#000000,blanchedalmond#ffebcd,blue#0000ff,\"\n\"blueviolet#8a2be2,brown#a52a2a,burlywood#deb887,cadetblue#5f9ea0,chartreuse#7fff00,\"\n\"chocolate#d2691e,coral#ff7f50,cornflowerblue#6495ed,cornsilk#fff8dc,crimson#dc143c,\"\n\"cyan#00ffff,darkblue#00008b,darkcyan#008b8b,darkgoldenrod#b8860b,darkgray#a9a9a9,\"\n\"darkgreen#006400,darkgrey#a9a9a9,darkkhaki#bdb76b,darkmagenta#8b008b,\"\n\"darkolivegreen#556b2f,darkorange#ff8c00,darkorchid#9932cc,darkred#8b0000,\"\n\"darksalmon#e9967a,darkseagreen#8fbc8f,darkslateblue#483d8b,darkslategray#2f4f4f,\"\n\"darkslategrey#2f4f4f,darkturquoise#00ced1,darkviolet#9400d3,deeppink#ff1493,\"\n\"deepskyblue#00bfff,dimgray#696969,dimgrey#696969,dodgerblue#1e90ff,\"\n\"firebrick#b22222,floralwhite#fffaf0,forestgreen#228b22,fuchsia#ff00ff,\"\n\"gainsboro#dcdcdc,ghostwhite#f8f8ff,gold#ffd700,goldenrod#daa520,gray#808080,\"\n\"green#008000,greenyellow#adff2f,grey#808080,honeydew#f0fff0,hotpink#ff69b4,\"\n\"indianred#cd5c5c,indigo#4b0082,ivory#fffff0,khaki#f0e68c,lavender#e6e6fa,\"\n\"lavenderblush#fff0f5,lawngreen#7cfc00,lemonchiffon#fffacd,lightblue#add8e6,\"\n\"lightcoral#f08080,lightcyan#e0ffff,lightgoldenrodyellow#fafad2,lightgray#d3d3d3,\"\n\"lightgreen#90ee90,lightgrey#d3d3d3,lightpink#ffb6c1,lightsalmon#ffa07a,\"\n\"lightseagreen#20b2aa,lightskyblue#87cefa,lightslategray#778899,\"\n\"lightslategrey#778899,lightsteelblue#b0c4de,lightyellow#ffffe0,lime#00ff00,\"\n\"limegreen#32cd32,linen#faf0e6,magenta#ff00ff,maroon#800000,mediumaquamarine#66cdaa,\"\n\"mediumblue#0000cd,mediumorchid#ba55d3,mediumpurple#9370db,mediumseagreen#3cb371,\"\n\"mediumslateblue#7b68ee,mediumspringgreen#00fa9a,mediumturquoise#48d1cc,\"\n\"mediumvioletred#c71585,midnightblue#191970,mintcream#f5fffa,mistyrose#ffe4e1,\"\n\"moccasin#ffe4b5,navajowhite#ffdead,navy#000080,oldlace#fdf5e6,olive#808000,\"\n\"olivedrab#6b8e23,orange#ffa500,orangered#ff4500,orchid#da70d6,palegoldenrod#eee8aa,\"\n\"palegreen#98fb98,paleturquoise#afeeee,palevioletred#db7093,papayawhip#ffefd5,\"\n\"peachpuff#ffdab9,peru#cd853f,pink#ffc0cb,plum#dda0dd,powderblue#b0e0e6,\"\n\"purple#800080,red#ff0000,rosybrown#bc8f8f,royalblue#4169e1,saddlebrown#8b4513,\"\n\"salmon#fa8072,sandybrown#f4a460,seagreen#2e8b57,seashell#fff5ee,sienna#a0522d,\"\n\"silver#c0c0c0,skyblue#87ceeb,slateblue#6a5acd,slategray#708090,slategrey#708090,\"\n\"snow#fffafa,springgreen#00ff7f,steelblue#4682b4,tan#d2b48c,teal#008080,\"\n\"thistle#d8bfd8,tomato#ff6347,turquoise#40e0d0,violet#ee82ee,wheat#f5deb3,\"\n\"white#ffffff,whitesmoke#f5f5f5,yellow#ffff00,yellowgreen#9acd32\";\n\n+ (UIColor *)searchForColorByName:(NSString *)cssColorName {\n\tUIColor *result = nil;\n\t\n\t\/\/ Compile the string we'll use to search against the database\n\t\/\/ We search for \",<colorname>#\" to avoid false matches<br \/>\n\tconst char *searchString = [[NSString stringWithFormat:@\",%@#\", cssColorName] UTF8String];<\/p>\n<p>\t\/\/ Search for the color name<br \/>\n\tconst char *found = strstr(colorNameDB, searchString);<\/p>\n<p>\t\/\/ If found, step past the search string and grab the hex representation<br \/>\n\tif (found) {<br \/>\n\t\tconst char *after = found + strlen(searchString);<br \/>\n\t\tint hex;<br \/>\n\t\tif (sscanf(after, \"%x\", &hex) == 1) {<br \/>\n\t\t\tresult = [self colorWithRGBHex:hex];<br \/>\n\t\t}<br \/>\n\t}<\/p>\n<p>\treturn result;<br \/>\n}<br \/>\n@end<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Here&#8217;s some handy code to extend UIColor, based largely on code by Erica Sadun, but with a couple of fixes and handy (to me) additions. Let me know if this is useful&#8230;<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,49],"tags":[],"class_list":["post-486","post","type-post","status-publish","format-standard","hentry","category-iphone-dev","category-programming"],"_links":{"self":[{"href":"https:\/\/www.juggleware.com\/blog\/wp-json\/wp\/v2\/posts\/486","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.juggleware.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.juggleware.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.juggleware.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.juggleware.com\/blog\/wp-json\/wp\/v2\/comments?post=486"}],"version-history":[{"count":6,"href":"https:\/\/www.juggleware.com\/blog\/wp-json\/wp\/v2\/posts\/486\/revisions"}],"predecessor-version":[{"id":492,"href":"https:\/\/www.juggleware.com\/blog\/wp-json\/wp\/v2\/posts\/486\/revisions\/492"}],"wp:attachment":[{"href":"https:\/\/www.juggleware.com\/blog\/wp-json\/wp\/v2\/media?parent=486"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.juggleware.com\/blog\/wp-json\/wp\/v2\/categories?post=486"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.juggleware.com\/blog\/wp-json\/wp\/v2\/tags?post=486"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}