Ad

Our DNA is written in Swift
Jump

HTML Colors

I am building a category for NSAttributedString that will allow me to make attributed strings from HTML code. For coloring the text there are two methods in HTML, via the deprecated font tag and via style. Both use color names or hex to describe the color.

The W3C knows 147 color names, clearly too many to type in manually. So I used a bit of shell script magic to hammer this into Objective-C. Then I also needed an elegant method to make regular UIColor objects from a hex string.

Both I am sharing in this article. These methods are invaluable if you are dealing with web people who are used to specifying colors this way. Also it might be more intuitive if you can specify colors in hex format yourself. That is, if you are a geek who is used to thinking in the hexadecimal system.

First I’m going to show you how to get a color from a hex string. Those strings are always 6 characters, two for red, green and blue each. Possible values are 00 through FF in the hexadecimal system describing the possible values in 1 byte, zero through 255.

A quick method to convert a string to the corresponding integer value. We are using a handy method of NSScanner which knows how to do the conversion. I put that into an NSString (HTML) category.

- (NSUInteger)integerValueFromHex
{
    NSScanner *scanner = [NSScanner scannerWithString:self];
    unsigned int result = 0;
    [scanner scanHexInt: &result];
 
    return result;
}

Next, we want to be able to get 3 such values from a string into a color. This went into my UIColor (HTML) category.

+ (UIColor *)colorWithHexString:(NSString *)hex
{
    // thanks mare! #rgb = #rrggbb
 
    if ([hex length]==3)
    {
        NSString *oneR = [hex substringWithRange:NSMakeRange(0, 1)];
        NSString *oneG = [hex substringWithRange:NSMakeRange(1, 1)];
        NSString *oneB = [hex substringWithRange:NSMakeRange(2, 1)];
 
        hex = [NSString stringWithFormat:@"%@%@%@%@%@%@", oneR, oneR, oneG, oneG, oneB, oneB];
    }
 
    if ([hex length]!=6)
    {
        return nil;
    }
 
    CGFloat red = [[hex substringWithRange:NSMakeRange(0, 2)] integerValueFromHex]/255.0;
    CGFloat green = [[hex substringWithRange:NSMakeRange(2, 2)] integerValueFromHex]/255.0;
    CGFloat blue = [[hex substringWithRange:NSMakeRange(4, 2)] integerValueFromHex]/255.0;
 
    return [UIColor colorWithRed:red green:green blue:blue alpha:1.0];
}

Originally I only allowed for a 6 character hex, but reader mare informed me that also 3 characters are valid. So I allowed for that case by duplicating the individual values. We get RGB in the range from zero to 255, but colorWithRed:green:blue:alpha: expects values between 0 and 1.0, hence the division by 255.

Ok, that was easy. Now for the promised shell scripting magic. (Or you could simply copy and paste my result)

First I copied the contents of http://www.w3schools.com/html/html_colornames.asp into a local text file colors.html.

On the shell I extracted the lines with the names and the lines with the hex codes.

grep "ref_color_tryit" colors.html | cut -f5 -d"=" | cut -f1 -d"\"" > colors.txt

Now we have the color name and hex code in alternating lines. To make this into Objective-C, I wrote a quick shell script:

while read line
 do
 
 if [ -z "$name" ]
 then
 name=`echo $line | tr [:upper:] [:lower:]`
 else
 code=$line
 
 echo "if ([name isEqualToString:@\"$name\"]) return [UIColor colorWithHexString:@\"$code\"];";
 name=""
 fi
 
 done

Notice that I am changing the color names to lower case because I want to be able to both write “red”, “Red” and “RED” for the color red. Package the result from the script into a method in our UIColor (HTML) category and we’re done.

+ (UIColor *)colorWithHTMLName:(NSString *)name
{
    name = [name lowercaseString];
 
    if ([name isEqualToString:@"aliceblue"]) return [UIColor colorWithHexString:@"F0F8FF"];
    if ([name isEqualToString:@"antiquewhite"]) return [UIColor colorWithHexString:@"FAEBD7"];
    if ([name isEqualToString:@"aqua"]) return [UIColor colorWithHexString:@"00FFFF"];
    if ([name isEqualToString:@"aquamarine"]) return [UIColor colorWithHexString:@"7FFFD4"];
    if ([name isEqualToString:@"azure"]) return [UIColor colorWithHexString:@"F0FFFF"];
    if ([name isEqualToString:@"beige"]) return [UIColor colorWithHexString:@"F5F5DC"];
    if ([name isEqualToString:@"bisque"]) return [UIColor colorWithHexString:@"FFE4C4"];
    if ([name isEqualToString:@"black"]) return [UIColor colorWithHexString:@"000000"];
    if ([name isEqualToString:@"blanchedalmond"]) return [UIColor colorWithHexString:@"FFEBCD"];
    if ([name isEqualToString:@"blue"]) return [UIColor colorWithHexString:@"0000FF"];
    if ([name isEqualToString:@"blueviolet"]) return [UIColor colorWithHexString:@"8A2BE2"];
    if ([name isEqualToString:@"brown"]) return [UIColor colorWithHexString:@"A52A2A"];
    if ([name isEqualToString:@"burlywood"]) return [UIColor colorWithHexString:@"DEB887"];
    if ([name isEqualToString:@"cadetblue"]) return [UIColor colorWithHexString:@"5F9EA0"];
    if ([name isEqualToString:@"chartreuse"]) return [UIColor colorWithHexString:@"7FFF00"];
    if ([name isEqualToString:@"chocolate"]) return [UIColor colorWithHexString:@"D2691E"];
    if ([name isEqualToString:@"coral"]) return [UIColor colorWithHexString:@"FF7F50"];
    if ([name isEqualToString:@"cornflowerblue"]) return [UIColor colorWithHexString:@"6495ED"];
    if ([name isEqualToString:@"cornsilk"]) return [UIColor colorWithHexString:@"FFF8DC"];
    if ([name isEqualToString:@"crimson"]) return [UIColor colorWithHexString:@"DC143C"];
    if ([name isEqualToString:@"cyan"]) return [UIColor colorWithHexString:@"00FFFF"];
    if ([name isEqualToString:@"darkblue"]) return [UIColor colorWithHexString:@"00008B"];
    if ([name isEqualToString:@"darkcyan"]) return [UIColor colorWithHexString:@"008B8B"];
    if ([name isEqualToString:@"darkgoldenrod"]) return [UIColor colorWithHexString:@"B8860B"];
    if ([name isEqualToString:@"darkgray"]) return [UIColor colorWithHexString:@"A9A9A9"];
    if ([name isEqualToString:@"darkgrey"]) return [UIColor colorWithHexString:@"A9A9A9"];
    if ([name isEqualToString:@"darkgreen"]) return [UIColor colorWithHexString:@"006400"];
    if ([name isEqualToString:@"darkkhaki"]) return [UIColor colorWithHexString:@"BDB76B"];
    if ([name isEqualToString:@"darkmagenta"]) return [UIColor colorWithHexString:@"8B008B"];
    if ([name isEqualToString:@"darkolivegreen"]) return [UIColor colorWithHexString:@"556B2F"];
    if ([name isEqualToString:@"darkorange"]) return [UIColor colorWithHexString:@"FF8C00"];
    if ([name isEqualToString:@"darkorchid"]) return [UIColor colorWithHexString:@"9932CC"];
    if ([name isEqualToString:@"darkred"]) return [UIColor colorWithHexString:@"8B0000"];
    if ([name isEqualToString:@"darksalmon"]) return [UIColor colorWithHexString:@"E9967A"];
    if ([name isEqualToString:@"darkseagreen"]) return [UIColor colorWithHexString:@"8FBC8F"];
    if ([name isEqualToString:@"darkslateblue"]) return [UIColor colorWithHexString:@"483D8B"];
    if ([name isEqualToString:@"darkslategray"]) return [UIColor colorWithHexString:@"2F4F4F"];
    if ([name isEqualToString:@"darkslategrey"]) return [UIColor colorWithHexString:@"2F4F4F"];
    if ([name isEqualToString:@"darkturquoise"]) return [UIColor colorWithHexString:@"00CED1"];
    if ([name isEqualToString:@"darkviolet"]) return [UIColor colorWithHexString:@"9400D3"];
    if ([name isEqualToString:@"deeppink"]) return [UIColor colorWithHexString:@"FF1493"];
    if ([name isEqualToString:@"deepskyblue"]) return [UIColor colorWithHexString:@"00BFFF"];
    if ([name isEqualToString:@"dimgray"]) return [UIColor colorWithHexString:@"696969"];
    if ([name isEqualToString:@"dimgrey"]) return [UIColor colorWithHexString:@"696969"];
    if ([name isEqualToString:@"dodgerblue"]) return [UIColor colorWithHexString:@"1E90FF"];
    if ([name isEqualToString:@"firebrick"]) return [UIColor colorWithHexString:@"B22222"];
    if ([name isEqualToString:@"floralwhite"]) return [UIColor colorWithHexString:@"FFFAF0"];
    if ([name isEqualToString:@"forestgreen"]) return [UIColor colorWithHexString:@"228B22"];
    if ([name isEqualToString:@"fuchsia"]) return [UIColor colorWithHexString:@"FF00FF"];
    if ([name isEqualToString:@"gainsboro"]) return [UIColor colorWithHexString:@"DCDCDC"];
    if ([name isEqualToString:@"ghostwhite"]) return [UIColor colorWithHexString:@"F8F8FF"];
    if ([name isEqualToString:@"gold"]) return [UIColor colorWithHexString:@"FFD700"];
    if ([name isEqualToString:@"goldenrod"]) return [UIColor colorWithHexString:@"DAA520"];
    if ([name isEqualToString:@"gray"]) return [UIColor colorWithHexString:@"808080"];
    if ([name isEqualToString:@"grey"]) return [UIColor colorWithHexString:@"808080"];
    if ([name isEqualToString:@"green"]) return [UIColor colorWithHexString:@"008000"];
    if ([name isEqualToString:@"greenyellow"]) return [UIColor colorWithHexString:@"ADFF2F"];
    if ([name isEqualToString:@"honeydew"]) return [UIColor colorWithHexString:@"F0FFF0"];
    if ([name isEqualToString:@"hotpink"]) return [UIColor colorWithHexString:@"FF69B4"];
    if ([name isEqualToString:@"indianred"]) return [UIColor colorWithHexString:@"CD5C5C"];
    if ([name isEqualToString:@"indigo"]) return [UIColor colorWithHexString:@"4B0082"];
    if ([name isEqualToString:@"ivory"]) return [UIColor colorWithHexString:@"FFFFF0"];
    if ([name isEqualToString:@"khaki"]) return [UIColor colorWithHexString:@"F0E68C"];
    if ([name isEqualToString:@"lavender"]) return [UIColor colorWithHexString:@"E6E6FA"];
    if ([name isEqualToString:@"lavenderblush"]) return [UIColor colorWithHexString:@"FFF0F5"];
    if ([name isEqualToString:@"lawngreen"]) return [UIColor colorWithHexString:@"7CFC00"];
    if ([name isEqualToString:@"lemonchiffon"]) return [UIColor colorWithHexString:@"FFFACD"];
    if ([name isEqualToString:@"lightblue"]) return [UIColor colorWithHexString:@"ADD8E6"];
    if ([name isEqualToString:@"lightcoral"]) return [UIColor colorWithHexString:@"F08080"];
    if ([name isEqualToString:@"lightcyan"]) return [UIColor colorWithHexString:@"E0FFFF"];
    if ([name isEqualToString:@"lightgoldenrodyellow"]) return [UIColor colorWithHexString:@"FAFAD2"];
    if ([name isEqualToString:@"lightgray"]) return [UIColor colorWithHexString:@"D3D3D3"];
    if ([name isEqualToString:@"lightgrey"]) return [UIColor colorWithHexString:@"D3D3D3"];
    if ([name isEqualToString:@"lightgreen"]) return [UIColor colorWithHexString:@"90EE90"];
    if ([name isEqualToString:@"lightpink"]) return [UIColor colorWithHexString:@"FFB6C1"];
    if ([name isEqualToString:@"lightsalmon"]) return [UIColor colorWithHexString:@"FFA07A"];
    if ([name isEqualToString:@"lightseagreen"]) return [UIColor colorWithHexString:@"20B2AA"];
    if ([name isEqualToString:@"lightskyblue"]) return [UIColor colorWithHexString:@"87CEFA"];
    if ([name isEqualToString:@"lightslategray"]) return [UIColor colorWithHexString:@"778899"];
    if ([name isEqualToString:@"lightslategrey"]) return [UIColor colorWithHexString:@"778899"];
    if ([name isEqualToString:@"lightsteelblue"]) return [UIColor colorWithHexString:@"B0C4DE"];
    if ([name isEqualToString:@"lightyellow"]) return [UIColor colorWithHexString:@"FFFFE0"];
    if ([name isEqualToString:@"lime"]) return [UIColor colorWithHexString:@"00FF00"];
    if ([name isEqualToString:@"limegreen"]) return [UIColor colorWithHexString:@"32CD32"];
    if ([name isEqualToString:@"linen"]) return [UIColor colorWithHexString:@"FAF0E6"];
    if ([name isEqualToString:@"magenta"]) return [UIColor colorWithHexString:@"FF00FF"];
    if ([name isEqualToString:@"maroon"]) return [UIColor colorWithHexString:@"800000"];
    if ([name isEqualToString:@"mediumaquamarine"]) return [UIColor colorWithHexString:@"66CDAA"];
    if ([name isEqualToString:@"mediumblue"]) return [UIColor colorWithHexString:@"0000CD"];
    if ([name isEqualToString:@"mediumorchid"]) return [UIColor colorWithHexString:@"BA55D3"];
    if ([name isEqualToString:@"mediumpurple"]) return [UIColor colorWithHexString:@"9370D8"];
    if ([name isEqualToString:@"mediumseagreen"]) return [UIColor colorWithHexString:@"3CB371"];
    if ([name isEqualToString:@"mediumslateblue"]) return [UIColor colorWithHexString:@"7B68EE"];
    if ([name isEqualToString:@"mediumspringgreen"]) return [UIColor colorWithHexString:@"00FA9A"];
    if ([name isEqualToString:@"mediumturquoise"]) return [UIColor colorWithHexString:@"48D1CC"];
    if ([name isEqualToString:@"mediumvioletred"]) return [UIColor colorWithHexString:@"C71585"];
    if ([name isEqualToString:@"midnightblue"]) return [UIColor colorWithHexString:@"191970"];
    if ([name isEqualToString:@"mintcream"]) return [UIColor colorWithHexString:@"F5FFFA"];
    if ([name isEqualToString:@"mistyrose"]) return [UIColor colorWithHexString:@"FFE4E1"];
    if ([name isEqualToString:@"moccasin"]) return [UIColor colorWithHexString:@"FFE4B5"];
    if ([name isEqualToString:@"navajowhite"]) return [UIColor colorWithHexString:@"FFDEAD"];
    if ([name isEqualToString:@"navy"]) return [UIColor colorWithHexString:@"000080"];
    if ([name isEqualToString:@"oldlace"]) return [UIColor colorWithHexString:@"FDF5E6"];
    if ([name isEqualToString:@"olive"]) return [UIColor colorWithHexString:@"808000"];
    if ([name isEqualToString:@"olivedrab"]) return [UIColor colorWithHexString:@"6B8E23"];
    if ([name isEqualToString:@"orange"]) return [UIColor colorWithHexString:@"FFA500"];
    if ([name isEqualToString:@"orangered"]) return [UIColor colorWithHexString:@"FF4500"];
    if ([name isEqualToString:@"orchid"]) return [UIColor colorWithHexString:@"DA70D6"];
    if ([name isEqualToString:@"palegoldenrod"]) return [UIColor colorWithHexString:@"EEE8AA"];
    if ([name isEqualToString:@"palegreen"]) return [UIColor colorWithHexString:@"98FB98"];
    if ([name isEqualToString:@"paleturquoise"]) return [UIColor colorWithHexString:@"AFEEEE"];
    if ([name isEqualToString:@"palevioletred"]) return [UIColor colorWithHexString:@"D87093"];
    if ([name isEqualToString:@"papayawhip"]) return [UIColor colorWithHexString:@"FFEFD5"];
    if ([name isEqualToString:@"peachpuff"]) return [UIColor colorWithHexString:@"FFDAB9"];
    if ([name isEqualToString:@"peru"]) return [UIColor colorWithHexString:@"CD853F"];
    if ([name isEqualToString:@"pink"]) return [UIColor colorWithHexString:@"FFC0CB"];
    if ([name isEqualToString:@"plum"]) return [UIColor colorWithHexString:@"DDA0DD"];
    if ([name isEqualToString:@"powderblue"]) return [UIColor colorWithHexString:@"B0E0E6"];
    if ([name isEqualToString:@"purple"]) return [UIColor colorWithHexString:@"800080"];
    if ([name isEqualToString:@"red"]) return [UIColor colorWithHexString:@"FF0000"];
    if ([name isEqualToString:@"rosybrown"]) return [UIColor colorWithHexString:@"BC8F8F"];
    if ([name isEqualToString:@"royalblue"]) return [UIColor colorWithHexString:@"4169E1"];
    if ([name isEqualToString:@"saddlebrown"]) return [UIColor colorWithHexString:@"8B4513"];
    if ([name isEqualToString:@"salmon"]) return [UIColor colorWithHexString:@"FA8072"];
    if ([name isEqualToString:@"sandybrown"]) return [UIColor colorWithHexString:@"F4A460"];
    if ([name isEqualToString:@"seagreen"]) return [UIColor colorWithHexString:@"2E8B57"];
    if ([name isEqualToString:@"seashell"]) return [UIColor colorWithHexString:@"FFF5EE"];
    if ([name isEqualToString:@"sienna"]) return [UIColor colorWithHexString:@"A0522D"];
    if ([name isEqualToString:@"silver"]) return [UIColor colorWithHexString:@"C0C0C0"];
    if ([name isEqualToString:@"skyblue"]) return [UIColor colorWithHexString:@"87CEEB"];
    if ([name isEqualToString:@"slateblue"]) return [UIColor colorWithHexString:@"6A5ACD"];
    if ([name isEqualToString:@"slategray"]) return [UIColor colorWithHexString:@"708090"];
    if ([name isEqualToString:@"slategrey"]) return [UIColor colorWithHexString:@"708090"];
    if ([name isEqualToString:@"snow"]) return [UIColor colorWithHexString:@"FFFAFA"];
    if ([name isEqualToString:@"springgreen"]) return [UIColor colorWithHexString:@"00FF7F"];
    if ([name isEqualToString:@"steelblue"]) return [UIColor colorWithHexString:@"4682B4"];
    if ([name isEqualToString:@"tan"]) return [UIColor colorWithHexString:@"D2B48C"];
    if ([name isEqualToString:@"teal"]) return [UIColor colorWithHexString:@"008080"];
    if ([name isEqualToString:@"thistle"]) return [UIColor colorWithHexString:@"D8BFD8"];
    if ([name isEqualToString:@"tomato"]) return [UIColor colorWithHexString:@"FF6347"];
    if ([name isEqualToString:@"turquoise"]) return [UIColor colorWithHexString:@"40E0D0"];
    if ([name isEqualToString:@"violet"]) return [UIColor colorWithHexString:@"EE82EE"];
    if ([name isEqualToString:@"wheat"]) return [UIColor colorWithHexString:@"F5DEB3"];
    if ([name isEqualToString:@"white"]) return [UIColor colorWithHexString:@"FFFFFF"];
    if ([name isEqualToString:@"whitesmoke"]) return [UIColor colorWithHexString:@"F5F5F5"];
    if ([name isEqualToString:@"yellow"]) return [UIColor colorWithHexString:@"FFFF00"];
    if ([name isEqualToString:@"yellowgreen"]) return [UIColor colorWithHexString:@"9ACD32"];
 
    return nil;
}

Matt Coneybeare pointed out that colors further down this list would need more CPU cycles. So here is an alternative that builds a dictionary the first time it is used and then color lookup is fast because of the hashing mechanism employed by the dictionary. Note that there is no release anywhere because this method relies on the OS freeing up an app’s memory once it terminated.

// outside of the implementation:
static NSDictionary *colorLookup = nil;
 
+ (UIColor *)colorWithHTMLName:(NSString *)name
{
    if (!colorLookup)
    {
        colorLookup = [[NSDictionary alloc] initWithObjectsAndKeys:
        @"F0F8FF",@"aliceblue",
        @"FAEBD7",@"antiquewhite",
        @"00FFFF",@"aqua",
        @"7FFFD4",@"aquamarine",
        @"F0FFFF",@"azure",
        @"F5F5DC",@"beige",
        @"FFE4C4",@"bisque",
        @"000000",@"black",
        @"FFEBCD",@"blanchedalmond",
        @"0000FF",@"blue",
        @"8A2BE2",@"blueviolet",
        @"A52A2A",@"brown",
        @"DEB887",@"burlywood",
        @"5F9EA0",@"cadetblue",
        @"7FFF00",@"chartreuse",
        @"D2691E",@"chocolate",
        @"FF7F50",@"coral",
        @"6495ED",@"cornflowerblue",
        @"FFF8DC",@"cornsilk",
        @"DC143C",@"crimson",
        @"00FFFF",@"cyan",
        @"00008B",@"darkblue",
        @"008B8B",@"darkcyan",
        @"B8860B",@"darkgoldenrod",
        @"A9A9A9",@"darkgray",
        @"A9A9A9",@"darkgrey",
        @"006400",@"darkgreen",
        @"BDB76B",@"darkkhaki",
        @"8B008B",@"darkmagenta",
        @"556B2F",@"darkolivegreen",
        @"FF8C00",@"darkorange",
        @"9932CC",@"darkorchid",
        @"8B0000",@"darkred",
        @"E9967A",@"darksalmon",
        @"8FBC8F",@"darkseagreen",
        @"483D8B",@"darkslateblue",
        @"2F4F4F",@"darkslategray",
        @"2F4F4F",@"darkslategrey",
        @"00CED1",@"darkturquoise",
        @"9400D3",@"darkviolet",
        @"FF1493",@"deeppink",
        @"00BFFF",@"deepskyblue",
        @"696969",@"dimgray",
        @"696969",@"dimgrey",
        @"1E90FF",@"dodgerblue",
        @"B22222",@"firebrick",
        @"FFFAF0",@"floralwhite",
        @"228B22",@"forestgreen",
        @"FF00FF",@"fuchsia",
        @"DCDCDC",@"gainsboro",
        @"F8F8FF",@"ghostwhite",
        @"FFD700",@"gold",
        @"DAA520",@"goldenrod",
        @"808080",@"gray",
        @"808080",@"grey",
        @"008000",@"green",
        @"ADFF2F",@"greenyellow",
        @"F0FFF0",@"honeydew",
        @"FF69B4",@"hotpink",
        @"CD5C5C",@"indianred",
        @"4B0082",@"indigo",
        @"FFFFF0",@"ivory",
        @"F0E68C",@"khaki",
        @"E6E6FA",@"lavender",
        @"FFF0F5",@"lavenderblush",
        @"7CFC00",@"lawngreen",
        @"FFFACD",@"lemonchiffon",
        @"ADD8E6",@"lightblue",
        @"F08080",@"lightcoral",
        @"E0FFFF",@"lightcyan",
        @"FAFAD2",@"lightgoldenrodyellow",
        @"D3D3D3",@"lightgray",
        @"D3D3D3",@"lightgrey",
        @"90EE90",@"lightgreen",
        @"FFB6C1",@"lightpink",
        @"FFA07A",@"lightsalmon",
        @"20B2AA",@"lightseagreen",
        @"87CEFA",@"lightskyblue",
        @"778899",@"lightslategray",
        @"778899",@"lightslategrey",
        @"B0C4DE",@"lightsteelblue",
        @"FFFFE0",@"lightyellow",
        @"00FF00",@"lime",
        @"32CD32",@"limegreen",
        @"FAF0E6",@"linen",
        @"FF00FF",@"magenta",
        @"800000",@"maroon",
        @"66CDAA",@"mediumaquamarine",
        @"0000CD",@"mediumblue",
        @"BA55D3",@"mediumorchid",
        @"9370D8",@"mediumpurple",
        @"3CB371",@"mediumseagreen",
        @"7B68EE",@"mediumslateblue",
        @"00FA9A",@"mediumspringgreen",
        @"48D1CC",@"mediumturquoise",
        @"C71585",@"mediumvioletred",
        @"191970",@"midnightblue",
        @"F5FFFA",@"mintcream",
        @"FFE4E1",@"mistyrose",
        @"FFE4B5",@"moccasin",
        @"FFDEAD",@"navajowhite",
        @"000080",@"navy",
        @"FDF5E6",@"oldlace",
        @"808000",@"olive",
        @"6B8E23",@"olivedrab",
        @"FFA500",@"orange",
        @"FF4500",@"orangered",
        @"DA70D6",@"orchid",
        @"EEE8AA",@"palegoldenrod",
        @"98FB98",@"palegreen",
        @"AFEEEE",@"paleturquoise",
        @"D87093",@"palevioletred",
        @"FFEFD5",@"papayawhip",
        @"FFDAB9",@"peachpuff",
        @"CD853F",@"peru",
        @"FFC0CB",@"pink",
        @"DDA0DD",@"plum",
        @"B0E0E6",@"powderblue",
        @"800080",@"purple",
        @"FF0000",@"red",
        @"BC8F8F",@"rosybrown",
        @"4169E1",@"royalblue",
        @"8B4513",@"saddlebrown",
        @"FA8072",@"salmon",
        @"F4A460",@"sandybrown",
        @"2E8B57",@"seagreen",
        @"FFF5EE",@"seashell",
        @"A0522D",@"sienna",
        @"C0C0C0",@"silver",
        @"87CEEB",@"skyblue",
        @"6A5ACD",@"slateblue",
        @"708090",@"slategray",
        @"708090",@"slategrey",
        @"FFFAFA",@"snow",
        @"00FF7F",@"springgreen",
        @"4682B4",@"steelblue",
        @"D2B48C",@"tan",
        @"008080",@"teal",
        @"D8BFD8",@"thistle",
        @"FF6347",@"tomato",
        @"40E0D0",@"turquoise",
        @"EE82EE",@"violet",
        @"F5DEB3",@"wheat",
        @"FFFFFF",@"white",
        @"F5F5F5",@"whitesmoke",
        @"FFFF00",@"yellow",
        @"9ACD32",@"yellowgreen", nil];
    }
 
    NSString *hexString = [colorLookup objectForKey:[name lowercaseString]];
 
    return [UIColor colorWithHexString:hexString];
}

This approach might take longer the first time it is called, but subsequent calls are way faster.

Now you can specify your view background color just like in HTML:

- (void)awakeFromNib
{
    self.backgroundColor = [UIColor colorWithHTMLName:@"red"];
}

This time the magic sauce in this tutorial is not some obscure method (except maybe for the one from NSScanner which I myself stumbled upon), but instead some shell scripting to transform data found on the web into something we can use in our code.

And just maybe it will make your your communication a tad more elegant if you can ask your designer which he prefers: “White Smoke” or “Light Gray”. A new standard in communication! πŸ™‚


Also published on Medium.


Categories: Recipes

11 Comments »

  1. This seems pretty inefficient with all the conditionals here. I would hate to see the performance when @”yellowgreen” is the main color πŸ™‚ You would be much better off keeping a dictionary of these values and using the name as the key.

  2. Well Sir Coney, how would you propose to add a static dictionary to a category method?

  3. Make a UIColor subclass instead, call it DTColor or something, then use it like self.backgroundColor = [DTColor colorWithHTMLName:@”red”];

  4. If it’s not 6 characters then we won’t bother, because it cannot be a valid string.

    In HTML colours can be defined as three characters. #fab is the same colour as #ffaabb.

    (BTW Commenting here is a real pain. I had to spent almost 10 minutes replying to emails. Plus a Safari freeze when reloading this page.)

  5. Thanks for your input, but I prefer it to be a UIColor category. But the dictionary holds promise. Will change the code to that.

  6. Thank you for your input mare! I have adapted the hex method to also take 3-character codes.

  7. I find your code for color conversion a bit too overweight.

    First, you instantiate and throw away three NSScanners just to do a simple conversion. Instead, I would make a call to sscanf:
    – (NSUInteger)integerValueFromHex {
    NSUInteger result = 0;
    sscanf([self UTF8String], “%x”, &result);
    return result;
    }

    Second, you don’t need to do all this string manipulation just to convert your 3-digit hex code to a 6-digit hex code. Actually, all you need to do for this conversion is a simple multiplication by 0x11, that is by 17.

    Even better, we don’t need that conversion at all! The fact is that the 3-digit scale (actually a 1-digit scale for each of the three hexadecimal numbers) has a resolution of 1/16 instead of 1/256 for the 6-digit scale (actually 2-digit). So all we need to do is just to divide by 15 (0xf) instead of 255 (0xff) πŸ™‚

    + (UIColor *)colorWithHexString:(NSString *)hex {
    if ([hex length]!=6 && [hex length]!=3) return nil;

    NSUInteger digits = [hex length]/3;
    CGFloat maxValue = (digits==1)?15.0:255.0;
    CGFloat red = [[hex substringWithRange:NSMakeRange(0, digits)] integerValueFromHex]/maxValue;
    CGFloat green = [[hex substringWithRange:NSMakeRange(digits, digits)] integerValueFromHex]/maxValue;
    CGFloat blue = [[hex substringWithRange:NSMakeRange(2*digits, digits)] integerValueFromHex]/maxValue;

    return [UIColor colorWithRed:red green:green blue:blue alpha:1.0];
    }

    I put in a digits variable to make the code more concise and better show the logic, but of course you can just duplicate the three CGFloat… lines and get rid of that variable if you find it clearer that way.

    Of course if we don’t need our NSString extension elsewhere we can be even more concise:

    + (UIColor *)colorWithHexString:(NSString *)hex {
    if ([hex length]!=6 && [hex length]!=3) return nil;

    NSUInteger digits = [hex length]/3;

    int red, green, blue;
    sscanf([[hex substringWithRange:NSMakeRange(0, digits)] UTF8String], “%x”, &red);
    sscanf([[hex substringWithRange:NSMakeRange(digits, digits)] UTF8String], “%x”, &green);
    sscanf([[hex substringWithRange:NSMakeRange(2*digits, digits)] UTF8String], “%x”, &blue);

    CGFloat maxValue = (digits==1)?15.0:255.0;
    return [UIColor colorWithRed:red/maxValue green:green/maxValue blue:blue/maxValue alpha:1.0];
    }

    HTH πŸ™‚

  8. thanks for that. I replaced my Git code with yours.

  9. A color value may either be a hexadecimal number or color names. Color numbers are prefixed by a hash mark. The color names are case-insensitive.

    [HTML Color](http://www.willvick.com/HTML/HTMLColor.aspx)

    [HTML Color Examples](http://www.willvick.com/HTML/HTMLExampleColor.aspx)

    [HTML Tutorial with examples](http://www.willvick.com/HTMLTutorialwithExamples.aspx)