Swift Swift: Using Color and UIColor in Swift Part 1: RGB

Not so Cheap Sunglasses. Watercolor. 2008

[Updated to Swift 2.0/iOS9.0 9/18/15 SJL – errors corrected 11/20/15]
I’m color blind, and that makes me a very good person to teach you about color and UIColor.  I’ve painted for many years and my color blindness does not detract but actually helps me pick colors.  These two examples, one a water-color of mine from 2008 and another I did with the Crayon Style App for iPhone were each done in less than six colors. I want to give you the secrets of good colors that I learned the hard way.

PIllow. Crayon Style App 2014. from a photo reference.
PIllow. Crayon Style App 2014. from a photo reference.

I originally thought I would show you how to use color in one blog post, but it turned into two. In this post I’ll show you how to work with colors, how to use the RGB colors and how to apply them to controls in Swift with UIColor. In the next post I’ll show you how to make colorful, well designed displays with HSB.

The RGB  and RGBA Colors

There are several ways to  select colors. For what most people think of as color, there are two important color identifying systems: RGB and HSB. The most useful to most programmers is the RGB or Red-Green-Blue color system.   As far back as the time of the Apple ][, RGB colors are easy to communicate as bytes. They are also the standard color space for CSS, so any CSS web color scheme with a little work will translate into an app UI’s color scheme.

RGB traditionally has been a value between 0 and 255, and CSS uses this numbering pattern in one of two ways:

strong { color: #ff0000 }           /* #rrggbb */
strong { color: rgb(255,0,0) }      

Each of the color components can be expressed separately as a value between 0 and 255, with 255 being the full color and 0 being no color.  The first number is red, the second green and the third blue. The code line above is for the color red, since it is all red and no other color.  We can express red as a hexadecimal number #ff0000.  In hexadecimal 00 is 0 and ff is 255 in decimal.  We have three two digit numbers stuffed into one number. Xcode for the UIColor class decided to use a CGFloat between 1 and 0 instead of an integer between 0 and 255 .  The code to make a red color would be:

let myRedColor = UIColor(
    red:1.0,
    green:0.0,
    blue:0.0,
    alpha:1.0)

Notice for a UIColor there is a fourth attribute: A for alpha. Alpha levels are the amount of transparency of a color, or how much of the color underneath we can see. For our purposes in this post we will stick with solid colors, an alpha of 1.0. Feel free to experiment with translucency and transparency on your own.

System Colors

There is a set of often used system colors which have their own methods.  For example, instead of the assignment above,  we can type for red:

let myRedColor = UIColor.redColor()

With the same result. There are fourteen colors and a special color clearColor which is an alpha of 0 .

The Apple System Colors with a color wheel of RGB primary and secondaries.
The Apple System Colors with a color wheel of RGB primary and secondaries. Click on image for a better view.

In the illustration I organized the colors in a color wheel for the primary and secondary colors. A primary color is one we base all other colors. This for RGB  is not surprisingly red, green and blue. There are colors we can make by equally mixing two of the primaries. These are known as secondaries, and for RGB, those are Cyan, Magenta and Yellow, which also make up another color system CMYK which we’ll mention more in the next post.  Beneath them we have five different shades of gray.  Beneath that, three colors that don’t fit in a RGB scheme easily: Orange, Purple, and Brown.

Labels and Buttons: A Color Demo Application.

Let’s make a demonstration project. Open a new project in Xcode with a single view named SwiftColorDemo

Set up your storyboard to look something like this, with a button in the upper left and a label in the upper right:

2015-09-18_07-45-56

I set this up in autolayout. You can of course just drag and drop the controls, and adjust accordingly. For those who want to set up in auto layout, I pinned the button to the top and left margin of the view and the label to the top and right margin of the view. I made the label and button of equal widths and equal heights. Then I pinned the label and button 20 points horizontally from each other. I made the button one third of the height of the view by selecting equal heights between the superview and button, and then making the button have a multiplier of 1:3. I aligned the Label and Button labels with a pin to the view below them and aligned them to the leading edge.  For the sliders. I pinned then horizontally to the left and right margin. I took the top slider and aligned it to the vertical center, then pinned the other teo slider to it vertically. The segmented control I pinned to the bottom,left and right margins. If you don’t understand any of that, you might find my book Practical Autolayout very useful, though for this example you don’t need it.

Open the assistant editor. Make an outlet for the label by control-dragging from the label to the code in the assistant editor to make an outlet named mysampleColorLabel.

@IBOutlet weak var mySampleColorLabel: UILabel!

Getting to the code, in ViewController.swift, Add this to viewDidLoad:

override func viewDidLoad() {
    super.viewDidLoad()
//Set the label's color with the System colors
    mySampleColorLabel.backgroundColor = UIColor.blackColor() 
    mySampleColorLabel.textColor = UIColor.whiteColor()
 }

Here we set the label’s text color to white and background to black using system colors. Let’s set the background of the button to gray using a more explicit reference to red green and blue. Add this under the text color for the label:

//Set the button's back ground with a RGB specfied color
//integer and a float both work -- this is gray
mySampleColorButton.backgroundColor = UIColor(
    red: 0.5,
    green: 128/255.0,
    blue: 0.5,
     alpha: 1.0)

The parameters in the UIColor initializer are a CGFloat between 1 and 0. We can take a number and divide it by 255.0 to get a fraction that is between these two numbers, as we did with the green, since 128/255.0 equals 0.5. When you have a palette figured out in integer RGB values this is the way to specify values.
We have a background for a button but setting the text color is a little  different. Buttons are controls which have states. If we set the color by the textColor property of titleLabel, the system will ignore it. Add the following to your viewDidLoad code:

//the right way to set a color on a button title
mySampleColorButton.setTitleColor(
    UIColor.whiteColor(),
    forState: UIControlState.Normal)

When setting the titleColor of a button, use the method setTitleColor and for most cases set it for a state of UIControlState.Normal

Let’s set the background property of the view. It may help to have a light, neutral color to help us see the bolder colors we will play with. The color represented by #fde8d7 is a peach color and works nicely for our purposes. You’ll find many colors and color palettes described in hex numbers on websites like colourlovers.com or colourpod.com which feature pre-made palettes. But often such sites will  often use the hexadecimal system to describe the color. Swift fortunately can represent integers as hex values. Take the first two digits of the hex number as red, the next two as green, and the last two as blue. Write them with 0x  prefixed to the number Red for #fde8d7 would be 0xfd for example. Using this we can make our background peach like this:

//set the background color to #fde8d7
view.backgroundColor = UIColor(
    red: 0xfd/255,
    green: 0xe8/255,
    blue: 0xd7/255,
    alpha: 1.0)

Build and run. We have color!

Screenshot 2014-10-02 07.12.46

Making a Simple Color Picker

Lets hook up the sliders and the segment control to change the colors of the button and label.

We will need outlets. From the storyboard to the assistant editor, control drag from the button, label,sliders and segmented control to make more outlets:

@IBOutlet weak var mySampleColorButton: UIButton!
@IBOutlet weak var redSlider: UISlider!
@IBOutlet weak var greenSlider: UISlider!
@IBOutlet weak var blueSlider: UISlider!
@IBOutlet weak var backgroundTextSegment: UISegmentedControl!

Now control drag from the sliders to make three actions, one action for each slider, then add this code to those actions:

@IBAction func redSliderChanged(sender: UISlider) {
    displayColors()
}
@IBAction func greenSliderChanged(sender: UISlider) {
    displayColors()
}
@IBAction func blueSliderChanged(sender: UISlider) {
    displayColors()
}

The three sliders call a method displayColor. Add this to your code:

 //MARK: - instance methods
func displayColors(){
let red = CGFloat(redSlider.value)
let blue = CGFloat(blueSlider.value)
let green = CGFloat(greenSlider.value)
let color = UIColor(
    red: red,
    green: green,
    blue: blue,
    alpha: 1.0)
if backgroundTextSegment.selectedSegmentIndex == 0 { 
    mySampleColorButton.backgroundColor = color
    mySampleColorLabel.backgroundColor = color
} else {
    mySampleColorButton.setTitleColor(
        color,
        forState: .Normal)
    mySampleColorLabel.textColor = color
}
mySampleColorLabel.text = String(
    format: "%i,%i,%i",
    Int(red * 255),
    Int(green * 255),
    Int(blue * 255))
let myTitleText = String(
    format: "%6.2f,%6.2f,%6.2f",
    Float(red),
    Float(green),
    Float(blue))
mySampleColorButton.setTitle(
    myTitleText,
    forState: .Normal)
}

The first three lines of the function take the values from the three sliders and make them into a color. Sliders return Float and UIColor works in CGFloat. These are not the same type, Swift is very cranky about type so we need to convert red, green and blue with a CGFloat initializer before we do anything else. Next, we checks which segment the user selected. If it is the first segment, the color gets applies to backgrounds. If not, the text color changes. The final lies of code set the text on the label and button to show what color the sliders selected.

You can build and run this code. Now play with the sliders and the control to make pretty colors.

Screenshot 2014-10-02 07.14.20

Adding Color to the Slider Thumbs

It would be nice to add some color to the sliders. It would be even better if the tint color reflected the value of that color. The thumbTintColor property of UISlider does let us do that, but there is a catch: you need to initialize the tint with a image. Add the following code to the viewDidLoad method to initialize the view.

//initialize sliders for tints with an image
let sliderImage = UIImage(named: "color knob")
redSlider.setThumbImage(
    sliderImage,
    forState:UIControlState.Normal)
greenSlider.setThumbImage(
    sliderImage,
    forState:UIControlState.Normal)
blueSlider.setThumbImage(
    sliderImage,
    forState:UIControlState.Normal)

This of course needs an image. I made the following one, which you can download by right clicking on it and save the image as color knob.

color knob

In the project navigator, open the Assets.xcassets file. Drag the image file you saved from finder into the list of images.

Now change the code for the sliders to this:

@IBAction func redSliderChanged(sender: UISlider) {
    let red = CGFloat(sender.value)
    sender.thumbTintColor = UIColor(
        red: red,
        green: 0.0,
        blue: 0.0,
        alpha: 1.0)
    displayColors()
}

@IBAction func greenSliderChanged(sender: UISlider) {
    let green = CGFloat(sender.value)
    sender.thumbTintColor = UIColor(
        red: 0.0,
        green: green,
        blue: 0.0,
        alpha: 1.0)
    displayColors()
 }
@IBAction func blueSliderChanged(sender: UISlider) {
     let blue = CGFloat(sender.value)
     sender.thumbTintColor = UIColor(
         red: 0.0,
         green: 0.0,
         blue: blue,
         alpha: 1.0)
     displayColors()
}

We get the slider’s value, and convert it to a CGFloat. We take that value and change the tint value of the slider for that color only, leaving the other two colors at 0.
Build and run and you start with the button image. Move the buttons and the color changes.

colorslider1

The image is any image if you never show it at all. Many people use the app icon. If you don’t want to show the image at all, you can change the color immediately after setting the image like this:

//give the sliders the initial color
redSlider.thumbTintColor = UIColor(
     red: 0.5,
     green: 0.0, 
     blue: 0.0, 
     alpha: 1.0)
greenSlider.thumbTintColor = UIColor(
     red: 0.0,
     green: 0.5,
     blue: 0.0,
     alpha: 1.0)
blueSlider.thumbTintColor = UIColor(
     red: 0.0,
     green: 0.0,
     blue: 0.5,
     alpha: 1.0)

Build and run. The image is gone
Screenshot 2014-10-02 07.18.38

Reading a UIColor to RGB values

There are times we need to get back an RGB value from a UIColor. For example our application has a bit of a bug that requires it. When we change from background to text, we lose the color data we had and the screen goes blank. The sliders do not reflect the current color data. When we switch from Background to text or vice versa, it would be good to change the sliders to reflect that change. Control-drag from the storyboard to the assistant editor to make an action for the segmented control like this:

 @IBAction func backgroundTextSegment(sender: UISegmentedControl) {
    }

There is a UIColor method getRed, however it is a bit tricky to use. Add the following code to this new method:

 @IBAction func backgroundTextSegment(sender: UISegmentedControl) {
// Create variables
    var r:CGFloat = 0
    var g:CGFloat = 0
    var b:CGFloat = 0
    var a:CGFloat = 0
    var myColor = UIColor()
//select the color you want to read from segment data
    if  sender.selectedSegmentIndex == 0{
        myColor = mySampleColorLabel.backgroundColor!
    } else {
        myColor = mySampleColorLabel.textColor
    }
//read the color and if it exists, set the sliders
    if myColor.getRed(&r, green: &g, blue: &b, alpha: &a){
        redSlider.setValue(Float(r), animated: true)
        greenSlider.setValue(Float(g), animated: true)
        blueSlider.setValue(Float(b), animated: true)
    }
}

The method getRed returns a Bool that it successfully found a color. It then does something odd: it places the colors in the parameters for the method, but as the well-named, totally evil type UnsafeMutablePointer<CGFloat>. We don’t want to mess with these — trust me on this. However there is an easy way to avoid them. In front of our variable name we have an & character, which tells the compiler to share and load the parameter value back into the variable. If the method finds a color, we set the sliders with animation, converting the CGFloats into Float values.

Build and run, switch between background and text, and the slider thumbs move from one side of the slider to the next, since it reads colors from the black and white label.

There is a Lot More to Cover

When I originally started this post I thought it would be a quick one. It turns out there are three parts I wanted to cover. This post covered much of UIColor using RGB and assigning color to controls. I need two more posts to cover UIColor with gray, alpha values and UIColor using HSB, which will include color matching, making rainbow buttons and making a workable palette. I will continue color in the next post, and I’ll discuss gray and gray tone palettes and alpha values in the newsletter. If you have not signed up for the newsletter, subscribe here where I will weekly include some cool stuff I don’t post on the blog.

The Whole Code

//
//  ViewController.swift
//  SwiftColorPlay
//
//  Created by Steven Lipton on 9/28/14.
//  Copyright (c) 2014 MakeAppPie.Com. All rights reserved.
//

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var mySampleColorButton: UIButton!
    @IBOutlet weak var mySampleColorLabel: UILabel!
    @IBOutlet weak var redSlider: UISlider!
    @IBOutlet weak var greenSlider: UISlider!
    @IBOutlet weak var blueSlider: UISlider!
    @IBOutlet weak var backgroundTextSegment: UISegmentedControl!

    let sliderImage = UIImage(named: &quot;color knob&quot;)

        //MARK: - Actions

    @IBAction func backgroundTextSegment(sender: UISegmentedControl) {

        var r:CGFloat = 0
        var g:CGFloat = 0
        var b:CGFloat = 0
        var a:CGFloat = 0
        var myColor = UIColor()
        if  sender.selectedSegmentIndex == 0{
            myColor = mySampleColorLabel.backgroundColor!
        } else {
            myColor = mySampleColorLabel.textColor
        }
        if myColor.getRed(&amp;r, green: &amp;g, blue: &amp;b, alpha: &amp;a){
            redSlider.setValue(Float(r), animated: true)
            greenSlider.setValue(Float(g), animated: true)
            blueSlider.setValue(Float(b), animated: true)
        }

    }

    @IBAction func redSliderChanged(sender: UISlider) {
        let red = CGFloat(sender.value)
        sender.thumbTintColor = UIColor(
            red: red,
            green: 0.0,
            blue: 0.0,
            alpha: 1.0)
        displayColors()
    }

    @IBAction func greenSliderChanged(sender: UISlider) {
        let green = CGFloat(sender.value)
        sender.thumbTintColor = UIColor(
            red: 0.0,
            green: green,
            blue: 0.0, 
            alpha: 1.0)
        displayColors()

    }
    @IBAction func blueSliderChanged(sender: UISlider) {
        let blue = CGFloat(sender.value)
        sender.thumbTintColor = UIColor(
            red: 0.0,
            green: 0.0,
            blue: blue,
            alpha: 1.0)
        displayColors()

    }

    //MARK: - instance methods
    func displayColors(){
        //create a color from the sliders.
    let red = CGFloat(redSlider.value)
    let blue = CGFloat(blueSlider.value)
    let green = CGFloat(greenSlider.value)
    let color = UIColor(
        red: red,
        green: green,
        blue: blue,
        alpha: 1.0)
        //apply the color to the background or text
    if backgroundTextSegment.selectedSegmentIndex == 0 {
        mySampleColorButton.backgroundColor = color
        mySampleColorLabel.backgroundColor = color
    } else {
         mySampleColorButton.setTitleColor(
             color,
             forState: .Normal)
         mySampleColorLabel.textColor = color
        }
    mySampleColorLabel.text = String(
         format: &quot;%i,%i,%i&quot;,
         Int(red * 255),
         Int(green * 255),
         Int(blue * 255))
    let myTitleText = String(
         format: &quot;%6.2f,%6.2f,%6.2f&quot;,
         Float(red),
         Float(green),
         Float(blue))
    mySampleColorButton.setTitle(
         myTitleText,
         forState: .Normal)
    }

    //MARK: - Life Cycle
    override func viewDidLoad() {
        super.viewDidLoad()

        //Set the label's color with the System colors
        mySampleColorLabel.backgroundColor = UIColor.blackColor()
        mySampleColorLabel.textColor = UIColor.whiteColor()

        //Set the button's back ground with a RGB specfied color
        // a hex number, and decimal and a 1-0 all work -- this is gray
        mySampleColorButton.backgroundColor = UIColor(red: 0x80/255, green: 128/255.0, blue: 0.5, alpha: 1.0)

        //This is syntactically correct but does nothing
        mySampleColorButton.titleLabel?.textColor = UIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 1.0)

        //the right way to set a color on a button title
        mySampleColorButton.setTitleColor(UIColor.whiteColor(), forState: UIControlState.Normal)
        mySampleColorButton.setTitleColor(UIColor.blackColor(), forState: UIControlState.Disabled)

        //set the background color to #fde8d7
        view.backgroundColor = UIColor(red: 0xfd/255, green: 0xe8/255, blue: 0xd7/255, alpha: 1.0)

        //initialize sliders for tints with an image
        let sliderImage = UIImage(named: &quot;color knob&quot;)
        redSlider.setThumbImage(sliderImage, forState:UIControlState.Normal)
        greenSlider.setThumbImage(sliderImage, forState:UIControlState.Normal)
        blueSlider.setThumbImage(sliderImage, forState:UIControlState.Normal)

    }

}

17 Replies to “Swift Swift: Using Color and UIColor in Swift Part 1: RGB”

  1. hi Steven:
    excellent tutorials (nice paintings too, color blind, really?)! I was wondering if there’s a way to change the date label colors after they’ve been created in Interface.storyboard, or do you have to create them with code from the gitgo? THANKS!

    1. Just to clarify, what do you mean by date labels? If you mean a full date in a UIlabel, set the textColor property. Doesn’t matter if you created them in the storyboard or in code.

      1. I made two, one for seconds, the other holds the date. They are in two separate groups. Not sure how to address them. How do I access their names to set properties for them?

      2. I killed the original labels and added new ones to the groups, one named seconds and put in:
        let outputFormatter = NSDateFormatter()
        outputFormatter.dateFormat = “M/d”
        let newDateString:String = outputFormatter.stringFromDate(date)

        seconds.setText(newDateString)

        in my if statements to test for input from a connected iPhone, I added for example:
        seconds.setTextColor(UIColor.redColor())
        I’ll look next into making a more specific color reference, but for now I’m on the right track. THANKS!
        p.s., please feel free to remove this clutter. I just wanted you to know it came out okay.

      3. I found this just now here: http://www.anthonydamota.me/blog/en/use-a-hex-color-code-with-uicolor-on-swift/:
        func UIColorFromRGB(colorCode: String, alpha: Float = 1.0) -> UIColor {
        var scanner = NSScanner(string:colorCode)
        var color:UInt32 = 0;
        scanner.scanHexInt(&color)

        let mask = 0x000000FF
        let r = CGFloat(Float(Int(color >> 16) & mask)/255.0)
        let g = CGFloat(Float(Int(color >> 8) & mask)/255.0)
        let b = CGFloat(Float(Int(color) & mask)/255.0)

        return UIColor(red: r, green: g, blue: b, alpha: CGFloat(alpha))
        }

        seconds.setTextColor(UIColorFromRGB(“ff8888”))

        yes!!!!!

  2. okay so I found out how to access the name directly, right clicked on the seconds container and found Referencing Outlets, dragged that into the InterfaceController.swift, named one “seconds” and the other “date” and produced:
    @IBOutlet weak var seconds: WKInterfaceDate!
    @IBOutlet weak var date: WKInterfaceDate!
    I looked into the Apple Developer program guide to see how to change/set the color of a WKInterfaceDate! but found it woefully short on examples. googling: swift “WKInterfaceDate!” func setTextColor(_ color: UIC… only pulled up seven or eight articles, three of which were the same Apple article. I presumed seconds was the new label name, but “seconds.textColor = UIColor.redColor()” produced an error looking for a member of seconds called textColor…

  3. First and foremost,

    Thank you for the awesome tutorials. This is my first time attempting this and I am a novice in app development at this point.

    When trying to create the “mySampleColorLabel”, I am getting errors with both background and text color. What can I do to fix this?

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s