Tip: Hex Colors

There’s lot of ways to represent colors. Crayons have names like Sea Green and Peach.

I used these two colors since I’m color blind and they once got me in serious trouble when I was young. I and many with color blindness can’t tell them apart easily. Knowing some other identifying system is critical in describing colors not only for the colorblind, but anyone trying to communicate colors.
As developers, we often use RGB colors. UIColor has a initializer for RGB, using CGFloat values between 0 and 1. One of the most common shorthands for RGB values used in web and graphic design applications is the six digit hex value.


UIKit does not include an initializer for this value. Fortunately with some bit masking you learned in a previous tip its easy to convert from a hex value to a UIColor. Let me show you how, and a quick tip to get a matching color.

Hex colors use eight bits, or two hex digits, to represent the three primary colors in an RGB color. The rightmost two digits are blue, next to that green and to the left red. If you separate to those numbers ranging from 0 – 255 you can divide them by 255 and get the values needed for UIColor.

On Github you can find the starter file, which has an application for setting the color of two buttons. I have a text field for entry, and a go button to press that entry.
Make a new function color

func color(from hexColorNumber:UInt32) -> UIColor {
}

I used a UInt32 here, so I can hold the 24 bits of the RGB value. I’ll use some of the tricks we learned in an earlier tip about bit masking. The blue is the rightmost 8 bits. I can use a bit mask to get only the blue bits.

let blue =  (hexColorNumber & 0x0000ff)

The eight bits to the left of blue are green. I can do the same thing for green,

let green = (hexColorNumber & 0x00ff00)

but I also will need to shift them back eight bits

let green = (hexColorNumber & 0x00ff00) >> 8

For red, I can follow a similar pattern, shifting sixteen bits to the right.

let red = (hexColorNumber & 0xff0000) >> 16

With these integer values between 0 and 255, I can convert them to CGFloat and divide by 255 to get a CGFloat between 1 and 0 as UIColor requires, returning the UIColor.

return UIColor(
    red: CGFloat(red) / 255.0,
    green: CGFloat(green) / 255.0,
    blue: CGFloat(blue) / 255.0,
    alpha: alpha
)

This is function that takes UInt32 and converts it into a UIColor. You might want a function that converts from String. Add another function.

func color(from string:String) -> UIColor{}

There’s a initializer for unsigned integers that uses a string representation of a number and radix, the base system for the number. It returns an optional value, returning nil if it cannot translate the number correctly. You’ll need to unwrap the result to use it. I’ll do that with a UInt32

if let colorNumber = UInt32(string, radix:16){
}

I can return a color from my first color function

return color(from: colorNumber)

If nil, I’ll return black.

return UIColor.black

Here’s little trick to get a decent matching color. Copy and paste the color(from: String) function. Change the name of the copy to colorComplement.
In the return, pass back NOT color number.

return color(from: ~colorNumber)

In hue, this is a complement, but the lightness and saturation of the color is also opposite.
Change the updateColor method to use these. Set the topButton‘s background color to the color, and its tint to the color complement

topButton.backgroundColor = color(from: colorString)
topButton.tintColor = colorComplement(from: colorString)

Then do the opposite with the bottom button.

bottomButton.backgroundColor = colorComplement(from: colorString, alpha: 1.0)
bottomButton.tintColor = color(from: colorString)

Set your simulator to iPhone 8 plus. Build and run. At the top you can enter a color.

I set teh code to default to  yellow which is FFFF00. With that, you get yellow on top and its complement on the bottom. The sea green with is a green-blue 54ff9f has complement of red with a little blue.

Of course, I didn’t include the alpha value here. Since you have enough space in a UInt32, you should be able to use this same technique to add transparency on your own.

This was a text version of the iOS Development Tips Weekly video series you can find at the Lynda.com and LinkedIn Learning libraries. The first week of a week’s tip will be available for free. After that, you will need a subscription to get access to it. Click the image at left  to view.

The Whole Code

This project is available for download on GitHub

//
//  ViewController.swift
//  HexColorComplement
//
//  Created by Steven Lipton on 2/9/18.
//  Copyright © 2018 Steven Lipton. All rights reserved.
//

import UIKit

class ViewController:UIViewController{
    
    @IBOutlet weak var topButton: UIButton!
    @IBOutlet weak var bottomButton: UIButton!
    @IBOutlet weak var textField: UITextField!
    
    
    //MARK: - Actions
    @IBAction func goButton(_ sender: UIButton) {
        textField.resignFirstResponder()
        updateColor(colorString: textField.text!)
    }
    
    @IBAction func newColor(_ sender: UIButton) {
        textField.becomeFirstResponder()
    }
    
    func color(from hexColorNumber:UInt32) -> UIColor{
        let blue = hexColorNumber & 0x0000ff
        let green = (hexColorNumber & 0x00ff00) >> 8
        let red = (hexColorNumber & 0xff0000) >> 16
        return UIColor(red: CGFloat(red) / 255.0 , green: CGFloat(green) / 255.0, blue: CGFloat(blue) / 255.0, alpha: 1.0)
    }
    
    func color(from string:String) -> UIColor{
        if let colorNumber = UInt32(string, radix:16){
            return color(from: colorNumber)
        } else {
            return UIColor.black
        }
    }
    
    func colorComplement(from string:String) -> UIColor{
        if let colorNumber = UInt32(string, radix:16){
            return color(from: ~colorNumber)
        } else {
            return UIColor.black
        }
    }
    func updateColor(colorString:String){
        topButton.backgroundColor = color(from: colorString)
        topButton.tintColor = colorComplement(from: colorString)
        bottomButton.backgroundColor = colorComplement(from: colorString)
        bottomButton.tintColor = color(from: colorString)
    }
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        updateColor(colorString:"ffff00")
    }
}


One Reply to “Tip: Hex Colors”

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.