Colors are beautiful! They’re all around us — even in our apps. But adding colors to your app can be difficult to manage; some may work together, while others may not. Even worse, if you select the wrong color combinations, your app’s visual elements may be difficult to see. That’s where Chameleon steps in!
Chameleon is a color management framework that makes it easy to add a splash of color to your app. In this tutorial, you’ll learn how to use Chameleon to do the following:
- Differentiate your UI with Chameleon’s hand-picked color palette
- Create just the right random colors
- Use hex codes to create
UIColor
s - Theme your entire app based on your favorite color
- Generate color schemes on the fly
- Ensure that your labels are always visible by using contrasting colors
- Keep all the status bar icons visible by contrasting them against their background
Getting Started
The starter project, HomeSplash, is an interior design app. You can paint things, like furniture, different colors to see how they’d look in your living room (ARKit integration still coming!). Use the Download Materials button at the top or bottom of this tutorial to download the starter project.
Once downloaded, open the starter project in Xcode using HomeSplash.xcworkspace, and give it a build and run. Tap one of the furniture items, and you’ll see the color picker. Select a color, and watch as it’s painted onto your living room set.
Take a look at the project and you’ll see that it consists of two view controllers:
- ViewController.swift: The root view controller containing the image views for the furniture
- ColorPickerViewController.swift: The palette of different colors that update the root view controller when selected
It also includes a utility class that paints an image with a color using Core Image, ImagePainter.swift. You don’t need to worry about this class now.
I know what you’re thinking! For an app about color, it’s pretty bland at the moment. But don’t worry, you’re about to liven things up.
Here’s what you’ll be doing to spruce it up:
- Change the
UIKit
colors to the sparkly Chameleon color palette - Apply different colors to different items based on color schemes
- Lighten or darken the painted furniture with a stepper control
- Generate random colors for when you’re not feeling too artistic
- Update the entire app’s theme to the selected color by using global theming
Building the color picker
One look at Chameleon’s API and you’ll notice plenty of references to flat colors. This raises the question:
What Are Flat Colors?
Flat colors, often referred to as solid colors, are generally regarded as colors with little to no gradient or changes in hue. They also have no transparency; their Alpha values are set to 1.0. In the context of Chameleon, whenever a method uses the term flat color, it’s referring to Chameleon’s Flat Color Palette.
The Flat Color Palette is a collection of 24 hand-picked colors in two shades, which gives you a total of 48 colors. When Chameleon talks about generating a flat color, it generates one from that palette.
Adding Flat Colors to the Picker
Open Main.storyboard and locate the Color Picker Scene.
Each of the different-colored squares represent the colors that the user can select. Right now, they’re the stock-standard UIKit colors. All of the colors are set in the storyboard, so if you want to play around with the different Flat Colors there, you need to add the Chameleon Storyboard Add-On.
Download the Chameleon Palette, which you can find on Chameleon’s GitHub page. This will allow you to access the Chameleon colors from Interface Builder.
Once downloaded, open it, and then run the Palette Installer.pkg.
You may get a security warning when running the Palette Installer. Read through the warning, and then allow the installation in your Mac’s Security and Privacy settings if you’re happy.
Choose Open Anyway and make your way through the installer.
Once the installation is complete, restart Xcode and open Main.storyboard.
In the Color Picker Scene, click on one of the Color Views and show the Attributes inspector.
Click on the dropdown next to the Background property, and select Other… from the list. You’ll be presented with a color picker.
Click on the Color Palettes tab (third from the left), and you’ll see the Color View’s color selected in the Apple Color Palette. This is the default color palette that you use when using the standard colors such as UIColor.green
.
Open the Color Palette dropdown, and you’ll see there are quite a few more palettes from which to choose, including the newly-added Chameleon Color Palette. Select it to see all of the beautiful new crayons you just added to your color arsenal! :]
Select some of your favorite flat colors and apply them to the nine Color Views in the storyboard. Build and run the app, and you’ll see the colors you choose from the palette.
UIKit
colors. They’re all declared as extensions on UIColor
, with color names starting with flat
:
let flatMint = UIColor.flatMint
let flatMintDark = UIColor.flatMintDark
Random Colors
The usual way to generate random colors is to pass random values to UIColor.init(red:green:blue:)
. Following this approach, it’s common to end up with a collection of colors that don’t fit well together.
With Chameleon, finding the perfect random color is easier because it’s a little less random. :] Take the following, for example:
// A random color from the Flat Color Palette
let randomFlatColor = UIColor.randomFlat
// A random color from the 24 light shades of the Flat Color Palette
let randomLightFlatColor = UIColor(randomFlatColorOf: .light)
// A random color from an array
let myFavoriteColors = [UIColor.red, UIColor.flatGreen, UIColor(white: 0.5, alpha: 1.0)]
let randomColorFromArray = UIColor(randomColorIn: myFavoriteColors)
// A random color from the Flat Color Palette except for those in the array
let reds = [UIColor.flatRed, UIColor.flatRedDark]
let random = UIColor(randomFlatColorExcludingColorsIn: reds)
You can see that most of the methods and properties return a color from the Flat Color Palette. The only exception is UIColor(randomColorIn:)
, which returns one of the colors passed into it.
Adding a Random Color to the Picker
Currently, the button titled “Random” in the color picker doesn’t actually do anything. However, with the help of Chameleon, that’s about to change!
Open ColorPickerViewController.swift and import Chameleon at the top of the file, like this:
import ChameleonFramework
Now, locate randomColorTapped(_:)
, and update the selected color to a random color by adding the following implementation:
let randomColor = UIColor.randomFlat
updateAndPop(color: randomColor)
This generates a random color from Chameleon’s palette. It then passes this color back to the initial view controller.
Build and run the app. Now, tap one of the furniture items to navigate to the color picker. Then, tap on the Random button. Cool! Your imaginary living room is now painted with the creativity of a random color generator. Huzzah!
Hex Color Codes
You may have noticed the button, Ray Wenderlich Green, doesn’t work either. You’ll fix that next — because honestly, who doesn’t want their furniture to be Ray’s favorite shade of green, right? :]
The hex color code for Ray Wenderlich Green is #0B560E
. But there’s no need to find a hex-to-RGB converter in order to use the standard UIColor
initializer.
Inside ColorPickerViewController
, locate rayWenderlichGreenTapped(_:)
, and add this bit of code:
let rayWenderlichGreen = UIColor(hexString: "0B560E")!
updateAndPop(color: rayWenderlichGreen)
This creates a UIColor
straight from the hex string, which is then used to update the selected color.
Build and run the app, and marvel at what your living room will look like after you paint it Ray Wenderlich Green!
Color Schemes
Whenever you’re working with more than one color, you want to make sure they work together. Let’s face it, the wrong combination of colors can lead to a UI that’s either too bland or too glaring. Luckily, for less artistic people such as myself, you can make use of color schemes.
A color scheme is a selection of colors that share a particular relationship. Chameleon can generate color schemes of three types:
- Analogous
- Complementary
- Triadic
Analogous colors are those that sit next to each other on a color wheel.
They live close to each other on the light spectrum. They also blend well together.
Complementary colors sit across from each other on a color wheel.
Their contrast makes for a striking UI.
Triadic colors are evenly spaced on a color wheel.
Use them to create a vivid, colorful design.
Creating Color Schemes from the Selected Color
Open Main.storyboard and find the first view controller. It has a segmented control with the default First, Second, Third segment titles:
Click on the segmented control and select the Attributes inspector. Change the titles for each segment as follows:
- Segment 0: Analogous
- Segment 1: Complementary
- Segment 2: Triadic
Changing button titles is fun and all, but the functionality is unaffected. To change this, open ViewController.swift and start by importing Chameleon.
import ChameleonFramework
Next, add this property beneath selectedColor
:
var selectedColorScheme = ColorScheme.analogous {
didSet {
paintImages()
}
}
This defines a color scheme with the initial value of ColorScheme.analogous
. Whenever the scheme updates, it calls paintImages()
.
Now, find the method stub for colorSchemeSelectionChanged(_:)
, and add the following code to update the selected scheme:
switch sender.selectedSegmentIndex {
case 0:
selectedColorScheme = .analogous
case 1:
selectedColorScheme = .complementary
case 2:
selectedColorScheme = .triadic
default:
return
}
The switch statement sets the selectedColorScheme
based on the selected segment.
Great work! The selected scheme is updated, and now you can use it to paint the images.
paintImages()
creates UIImage
s for the image views and paints them with the selected color. It’s time to change it so that it paints the images with colors from a color scheme. Update paintImages()
to the following:
func paintImages() {
let baseColor = selectedColor
// 1
let colorsFromScheme = ColorSchemeOf(selectedColorScheme,
color: baseColor,
isFlatScheme: false)
// 2
imageView.image = imagePainter.paint(image: UIImage(named: "sofa"),
color: colorsFromScheme[1])
imageView2.image = imagePainter.paint(image: UIImage(named: "armchair"),
color: colorsFromScheme[2])
imageView3.image = imagePainter.paint(image: UIImage(named: "bookshelf"),
color: colorsFromScheme[3])
}
Here’s a closer look at what’s happening:
- Generate an array of colors from the selected scheme.
- For each image, grab a color from the
colorsFromScheme
array and use it to paint the image. Index 2 is theselectedColor
. You then use it to paint the center image.
Build and run the app. Select your favorite color, and take a look at your new interior design abilities! :]
Shades
The variety of colors for the living room grew three-fold by introducing schemes. Now you’ll add even more possibilities by adding shades :]
In Main.storyboard, take a look at the Shade Stepper.
Its initial value is 0, and it can range from -100 to 100. It steps in values of 10s. You’ll use this value to shade the selected color by a certain percentage.
In ViewController.swift, find selectedColor
, and create a new property below it:
var selectedColorWithShade: UIColor {
// 1
let shadePercentage = CGFloat(abs(stepperValue / 100))
if stepperValue >= 0 {
// 2
return selectedColor.lighten(byPercentage: shadePercentage)!
} else {
// 3
return selectedColor.darken(byPercentage: shadePercentage)!
}
}
Here’s what’s happening:
stepperValue
holds the value of the stepper. Use its value to create aCGFloat
between 0.0 and 1.0 representing the shade percentage.- If the stepper’s value is positive, use
lighten(byPercentage:)
to shade the color lighter. - If the stepper’s value is negative, use
darken(byPercentage:)
to shade the color darker.
Now, back to paintImages()
where all the magic happens. The first line of the method sets the color you’ll use to create the color scheme for the images.
let baseColor = selectedColor
Change this line to use the shaded color as the base color instead:
let baseColor = selectedColorWithShade
Great! Now build and run the app, and play around with the stepper. Now you can design a living room set for even the most pickiest of couch potatoes :]
Theming the App
The color picker has reached its final form! But the app itself is still looking rather dull. Luckily, Chameleon still has a few tricks up its sleeves.
In ViewController.swift find updateAppTheme()
, which fires whenever you update selectedColor
. Give the method the following implementation:
Chameleon.setGlobalThemeUsingPrimaryColor(selectedColor, with: .contrast)
And before you can say Voilà, you’ve updated the entire app’s theme!
Build and run the app. Now, select a new color, and see how this simple bit of code adds some liveliness to the app.
There are a few problems, though. For instance, the stock-standard UIButton
s in the Color Picker don’t look so great with the new theming.
Fortunately, you can fix that with a bit of styling. In ColorPickerViewController.swift, locate styleButtons()
. Add the following code to make the buttons a bit more pleasing to the eye:
buttons.forEach {
$0.layer.cornerRadius = 10
$0.contentEdgeInsets = UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8)
}
buttons
is an IBOutletCollection
that contains the offending Random and Ray Wenderlich Green buttons. styleButtons()
rounds the borders of each button and applies an inset to give them some padding. Build and run to see the difference.
There’s another interesting thing to note with the global app theming. Were you wondering what .contrast
does in the line of code you added to updateAppTheme()
? That’s the UIContentStyle
.
It can be one of three values:
UIContentStyle.contrast
UIContentStyle.light
UIContentStyle.dark
Build and run the app, and select a dark color from the color picker. Take a look at the text color of the buttons in the color picker:
Now, select a light color.
UIContentStyle.contrast
ensures that the text is always readable; you get white text on dark backgrounds, and black text on light backgrounds.
Setting the global app theme gets you most of the way to a snazzy app, but there’s still some work to do! Such as, the navigation bar is still white. It’d look much better if it matched the app’s theme. To do this, inside ViewController.swift you can update its tint color in updateAppTheme()
by adding:
navigationController?.navigationBar.barTintColor = selectedColor
Do a build and run. Then select a few different colors.
Uh-oh! The navigation bar still isn’t correct. The title doesn’t update to contrast the bar’s tint color. The status bar also stays the same, making it difficult to read.
Thankfully, Chameleon can fix that too!
Adding Contrast
To fix this discrepancy between the colors of the back button and navigation title, ensure that the navigation bar title color contrasts the selectedColor
. Add the following to the end of updateAppTheme()
:
let contrastingColor = UIColor(contrastingBlackOrWhiteColorOn:selectedColor,
isFlat: true)
navigationController?.navigationBar.titleTextAttributes = [.foregroundColor : contrastingColor]
Great! With that addition, updateAppTheme()
should look like this.
func updateAppTheme() {
Chameleon.setGlobalThemeUsingPrimaryColor(selectedColor, with: .contrast)
navigationController?.navigationBar.barTintColor = selectedColor
let contrastingColor = UIColor(contrastingBlackOrWhiteColorOn:selectedColor, isFlat: true)
navigationController?.navigationBar.titleTextAttributes =
[.foregroundColor : contrastingColor]
}
It’s time for another build and run. This time, the navigation bar’s text always updates to contrast the background.
Setting the global app theme like you did earlier with setGlobalThemeUsingPrimaryColor(_:with:)
will update the status bar as well. So why isn’t it changing?
To fix the status bar, open Info.plist. Hover over Information Property List, and tap the plus button to add a new property. Enter View controller-based status bar appearance as the name, set the type to Boolean and the value to NO.
This is all you need to give Chameleon control over the status bar. Build and run the app, and you should see the navigation bar’s back button, title, and the status bar, all change as you switch colors.
Gradient Colors
You’ve applied global app theming and you did the extra work to keep the colors compatible with each other. Now, there’s one last change you can do to make the app stand out.
In ViewController.swift, find showColorPicker(_:)
, and add the following line before calling navigationController?.pushViewController
:
colorPicker.view.backgroundColor = selectedColor
This will set the color picker’s background color to the last color you selected. Give it a build run, and take a look.
No, thanks! The selected color blends in with the buttons, the navigation bar, and the other colors. A gradient color would work better here. You can add some life to the empty part of the color picker while keeping the rest of it with a plain, white background.
Remove the line of code that you added to showColorPicker(_:)
and replace it with this:
colorPicker.view.backgroundColor = UIColor(gradientStyle: .topToBottom,
withFrame: colorPicker.view.frame,
andColors: [.flatWhite, .flatWhite,
selectedColor])
This sets the background color to a top-to-bottom gradient. The top two-thirds is Chameleon’s flat white and the bottom one-third is the selected color. You pass colorPicker.view.frame
for Chameleon to determine how to break up the different colors in the gradient.
You’re done! Build and run the app, and take a look at your finished product.
Where To Go From Here?
As you’ve seen, Chameleon lets you work with colors and theme your app with ease. You can download the completed version of the project using the Download Materials button at the top or bottom of this tutorial.
Don’t forget to take a look at the Chameleon Documentation to stay up-to-date with all the new features.
Do you want to learn more about Color Theory? Building the projects from our iOS Tutorials will help to develop an eye for UI design.
If you have any questions about this tutorial, or about Chameleon and color theory in general, we’d love to hear from you in the discussion forum below!
The post Chameleon on iOS: Getting Started appeared first on Ray Wenderlich.