UIColor from hex string, once again

I end up doing this once per year – at least it’s getting leaner each time.

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
44
45
46
47
48
49
50
51
52
static inline NSInteger NSIntegerFromHexDigit(const unichar c)
{
  switch( c ) {
  case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
    return c - '0';
  case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
    return c - 'a' + 10;
  case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
    return c - 'A' + 10;
  default:
    return -1;
  }
}
 
typedef NSUInteger RGBA32;
 
/** RGBA hex color matching /^(?:0x|#)?([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})?$/i
 */
static BOOL RGBAFromNSStringHex(NSString *hex, RGBA32 *value)
{
  const NSUInteger len = hex.length;
  if( len < 6 || len > 9 )
    return NO;
  unichar buffer[len];
  [hex getCharacters:buffer range:NSMakeRange(0, len)];
 
  // check if either 6 or 8 char hex
  const BOOL hasHashPrefix = buffer[0] == '#';
  const NSInteger netlen = len - hasHashPrefix;
  if( netlen != 6 && netlen != 8 )
    return NO;
 
  // turn hex to integer
  NSUInteger ret = 0;
  assert(sizeof(ret) >= 4); // need at least 4 bytes
  for( NSInteger i = hasHashPrefix; i < len; i++ ) {
    const NSInteger v = NSIntegerFromHexDigit(buffer[i]);
    if( v < 0 )
      return NO;
    ret <<= 4;
    ret |= v;
  }
  // if 6-char hex assume alpha 0xFF
  if( netlen == 6 ) {
    ret <<= 8;
    ret |= 0xFF;
  }
 
  if( value )
    *value = ret;
  return YES;
}

How to get a UIColor from here should be straightforward.

P.S.: Wikipedia about ‚RGBA‘

Flattr this!

Comments 1

  1. Marcus Rohrmoser wrote:

    Ha – just found Erica Sadun has a nice UIColor category, as well!

    Posted 10 Dez 2013 at 9:30 pm

Post a Comment

Your email is never published nor shared. Required fields are marked *