For an app I am working on, I wanted to use some specific colors outside of the standard system ones. Using UIColor is pretty easy, but I thought I would share with you how to use it in its simplest form, and a help category I made to make working with the built in functions a bit easier, and a tool I JUST found while working on this post that would have been very nice last week. If you want to learn how to make a category, see my previous post Objective-C Categories.
Creating a UIColor Object
UIColor has several methods to generate a color based off of components. The available ones are:
- colorWithWhite:alpha:
- colorWithHue:Saturation:brightness:alpha:
- colorWithRed:green:blue:alpha:
- colorWithCGColor:
- colorWithPatternImage:
- colorWithCIColor:
But we are going to work with colorWithRed:green:blue:alpha: in this post.
Also, each of those has an init form (so colorWithRed:green:blue:alpha: is initWithRed:green:blue:alpha: ). This makes less difference in a post ARC world, but for reference, the initWith forms give your class ownership of the object, and so it must be released when you are done with it to avoid memory leaks. The colorWith form (also called a “Factory Method”), does not give your class ownership, so it does not need to be released by your class, that is handled by the system. Since ARC automatically counts your references, they are effectively the same for the programmer nowadays.
[UIColor colorWithRed:green:blue:alpha: ]
I feel that this is the easiest way to generate a UIColor, all you need is the RGB values, that you can get from any image editor. One hitch to me though, is that RGB values are usually given as an integer between 0 and 255. This method though, only takes CGFloat values between 0.0 and 1.0. Nothing difficult, it just is the percentage value, so a Red value of 204 would be 204/255 = 0.8.
But I didn’t want to have to do that calculation myself every time I wanted to put in a color, so I made a category for UIColor to add a helper method to take those numbers directly. I have simplified it a bit here and taken out some bound-checking for clarity, but that should probably be added for production code:
+ (UIColor *)colorWithRed:(NSInteger)inputRed Green:(NSInteger)inputGreen Blue:(NSInteger)inputBlue { CGFloat newRed = inputRed/255.0; CGFloat newGreen = inputGreen/255.0; CGFloat newBlue = inputBlue/255.0; return [UIColor colorWithRed:newRed green:newGreen blue:newBlue alpha:1.0]; }
So it takes in NSInteger values of red, green and blue, then divides them by 255.0. I divide it with the “.0” on it to force it to be interpreted as a floating point value, and this will generate floating point values that can be placed into CGFloat variables. I then create the color, and hard code the alpha to 1.0. The alpha controls the opacity of the color, so anything less than 1.0 is partially transparent. With nothing behind what I was coloring, it just made the colors darker (mixing it with the black of the nothingness behind it). I just simply hardcoded the value to 1.0 for my helper method because I just want this method to make fully-opaque colors, and don’t want to type that alpha value every time.
In my version, there is a bit more work to verify that the numbers are capped at 0 and 255, so if something lower or higher is set, they will simply be set to the appropriate bound (so a value of 300 would come out as 255). So in a real version, you should probably add that, but this gives you the important part of dealing with UIColor.
What is CGFloat?
One interesting side not about this, CGFLoat is basically a float that is appropriate for the system, like NSInteger. If you click in to its definition, you see this:
typedef CGFLOAT_TYPE CGFloat;
#define CGFLOAT_DEFINED 1
Okay, nothing too special there, but you do see that the typdef sets whatever CGFLOAT_TYPE to be referred to as CGFloat. I am not sure where CGFLOAT_DEFINED is use though. Anyway, so what is CGFLOAT_TYPE? Well, if you look right above it…
#if defined(__LP64__) && __LP64__
# define CGFLOAT_TYPE double
# define CGFLOAT_IS_DOUBLE 1
# define CGFLOAT_MIN DBL_MIN
# define CGFLOAT_MAX DBL_MAX
#else
# define CGFLOAT_TYPE float
# define CGFLOAT_IS_DOUBLE 0
# define CGFLOAT_MIN FLT_MIN
# define CGFLOAT_MAX FLT_MAX
#endif
The if statement is checking if you are on a 64-bit system, like the iPhone 5s. If it is, CGFLoat is defined as a double, sets CGFLOAT_IS_DOUBLE to let you check that if you want, and sets the min and max for CGFloat to the min and max of a double. If you aren’t on a 64-bit system, then all of that is set to the appropriate float values.
Too geeky? Maybe, but I thought it was cool.
The tool I found: uicolor.org
So, when I was starting to look up some references to help me, I found http://uicolor.org/ . It is a very simple website, but it gets the job done. It shows a color picker, and you can just select an area of that, it will show your the RGB values (or the Hue, Saturation, and Brightness, if you like that sort of thing), and it even generates the Objective C code to generate the color directly! So, for a nice forest green color I found in the color picker, it generated this command for me:
UIColor * color = [UIColor colorWithRed:113/255.0f green:175/255.0f blue:109/255.0f alpha:1.0f];
Pretty cool, eh?
Although one small note, below the text box to copy it, it says to press Ctrl+C to copy. Unless you changed your keybindings, or are doing the text on a Windows machine for some reason, you will have to use Cmd+C.
I hope you found this article helpful. If you did, don’t hesitate to share this post on twitter or your social media of choice. The blog is still pretty new, and every share helps. Of course, if you have any questions, don’t hesitate to contact me on twitter @CodingExplorer, and I’ll see what I can do. Thanks!