iOS — Extend UIColor with custom colors
Written by Boris Ohayon | August 29, 2016
Today, we learn how to create and quickly access custom colors in Swift 💪
While building apps, I realized that I often needed to quickly assign a color to something. Most of the time, as I’m quite in love with flat design and flat colors, I would type in google flat colors and find this image :
Then I would open a color picker to get the RGB values of the chosen color. Finally, I would open Xcode and create a color with those values 🙄 Boring uh ?
This method is quite upsetting because every time:
- I have to open Safari and search for the image
- Open a color picker
- Create a color with the RGB values and add an ugly division by 255
What I needed was something as simple as UIColor.redColor(), as existed prior to Swift 3, and UIColor.red as of Swift 3.
I came up with a pretty simple solution : extend UIColor with a custom struct ! Let’s jump right in ! 🙃
Step 1— Create a new iOS project
Create a new project, nothing new here. Select Swift as the language and you’re done.
Step 2— Read a color with a hex value — Part 1
Most of the time when specifying a color, writing RGB values is boring, as opposed to having the hex value of the color. No native UIColor init can give a color given the hex value, so we’ll have to write one.
The first step is to get the RGB values from the hex. This is done with a little bit of bitwise operations, you can skip the next part explaining how we will proceed, if you want.
👮 What is a hex value ?
👮 How can we play with it and extract interesting info ?
Step 3 (optional)— Let’s play with hex
For example, in the image above with the flat colors, one I really like is Terra Cotta, its hex value being 0xE66B5B (note that the first character is a zero). We want to extract the RGB values from this hex, but for this, we have to master and understand what a hex value is and how it is made.
Under the hood, a hex value is just an integer. You can check this pretty quickly by opening a Playground :
The first two characters are 0 (zero) and x (letter x), specifying that what follows is a hexadecimal number. Then, it is composed of several hexadecimal digits, digits that can be 0 1 2 3 4 5 6 7 8 9 A B C D E F : 16 values possible. 👌 Now, we know that something that can take 16 values has to be coded on 4 bits because 2⁴ is 16. Two of those digits combined can then express a number between 0 and 255, because 16*16 is 256 possible values !
🤓 Let’s break it down, in the hex expression of Terra Cotta 0xE66B5B we have :
- 0x specifies that it’s a hexadecimal value
- E6 is the red
- 6B is the green
- 5B is the blue
Now, to get the red part of the hex value, we shift towards the right but how many bits ? 🤔
We see that we have to get rid of the 4 hex values to the right of E6, blue and green, that is 6, B, 5 and B, each coded on 4 bits, which is 16 bits total.
We then take the hex and shift it 16 bits :
As we can see, after shifting, we get 230, which exactly the value we expected, 0xE6 as we can see with the testValue above, or just by doing a simple check :
- E is 14 in hexadecimal and is at position 1, hence 14*16¹ = 224
- 6 is 6 in hexadecimal and is at position 0, hence 6*16⁰ = 6
- 224 + 6 = 230
To isolate the green component, another step is needed. If we shift 0xE66B5B 8 bits to the right, that gives us 0xE66B, and to only get 6B, the rightmost part of the expression, we can do an & (AND) operator.
Here is 0xE66B in binary:
Because we want to select only the two last hex values (6 and B), we are going to apply the following mask, 0xFF:
Now, the & operator is applied bit by bit:
- 1 & 1 = 1
- 1 & 0 = 0
- 0 & 1 = 0
- 0 & 0 = 0
Basically, when we apply a mask to another value, it selects everything that is 1 in the mask and puts to 0 everything else.
If we come back to what we need, after shifting and the & operation, we finally selected the part we wanted, 6B.
( 0xE66B5B >> 8 ) & 0xFF = 0x6B
To isolate the blue component, we don’t need to shift, we just want the rightmost part of the starting expression. We know how to do that : &!
( 0xE66B5B ) & 0xFF = 0x5B
👮 Now, as a safety, let’s just come back to the red component selection. Imagine that as an input we give a hexadecimal number with more than 6 hexadecimal digits, that will output something greater than 255 because we just shifted without selecting anything. To prevent this, we’ll just add a selection step as we did to the green and the blue to be sure to select something that is in the right range :
( 0xE66B5B >> 16 ) & 0xFF = 0xE6
🤓 To sum things up :
Step 4 — Create a color with RGB values
Create a new Swift file named UIColor+Hex. As we want to work with UIColor, we have to replace the import Foundation by import UIKit. By the way, writing both imports would make redundant imports, as UIKit already imports Foundation.
Now that we have isolated the red, the green and the blue, we can create a color with those values, as UIColor already has an init that does this : init(red:green:blue:alpha).
Nonetheless, we can add a convenience init that :
- enables us to create a color without specifying the alpha
- checks if the the values are in a legal range [0, 255]
This is pretty straightforward using assert. 🤓 Remember that assert only affects debug mode, not release mode where asserts are omitted. Using assert is not compulsory here as creating a color with a component greater than 255 won’t trigger a crash but that component would just be toned down to 255.
First, create an extension of UIColor in our newly created file, and then our convenience init, as follows :
Note that we’re using a convenience init, as convenience initializers are initializers used to make initialization a bit easier : we then have to eventually call a designated initializer, here init(red:green:blue:alpha).
Step 5 — Read a color with a hex value — Part 2
Now that we have a convenience init to create a color with RGB, and that as explained in part 3, we can extract the RGB values from the hex, things are pretty simple now. We just have to add our convenience init that creates a UIColor given a hex.
If I want to create a Terra Cotta color given its hex, I just have to do the following :
Easy, right ?
Step 6 — Extend UIColor to add a custom struct
Finally, the interesting part where we add our custom colors 😘
Create a new Swift file named UIColor+FlatColors.swift. As we previously did, replace the import Foundation by import UIKit.
When extending a type, we can easily add structs to them. Here, we’re going to divide by color. Either we can create a huge struct containing all the flat colors, or we can create several structs inside a parent struct which can be easier to work with, as shown in below.
Now, inside each struct, we want to add colors, as shown in the example part 5, with one major difference. As the properties belong to the class and not to an instance of a class, we have to add the static keyword. We then can populate the body established before, roughly separating the colors according to my perception :
Final step — Try it out !
Now, in any Swift file of your project, you can just create a color very quickly with one cute little line :
Isn’t that awesome ? 😜
🤘 That’s it !
You are now free to instantiate flat colors very quickly, or any colors of your choosing ! 😎
Like what you read? Let’s hit the ❤️ button so that everybody can read it too!
Want to support those tutorials? A bitcoin donation is always fun! 19MZUSLWszAdkaKVJNwrcVwgfvHxvqNMVU