Adding Gradient Colors to your View (UIView, UIButton, UILabel, etc.) - UIKit

We all have come across apps with gradient colors in them. Some look elegant, some roughly done. It depends upon what your UI designer asked you to make. I have seen some pretty gradient color combinations, and the worse too. We can’t add gradient colors directly to our button in the storyboard, but we can do that in our code. There are so many tweaks we can do with that. I can’t wait to tell you about it, so let’s get started.

Getting Started

Create a new UIKit project, and in your Main.storyboard inside your View Controller, drag and drop a UIButton and create an IBOutlet for the same and name it gradientButton. So that you don’t face any confusion over the word, give the button a Leading and Trailing constraint of value 20, Height of 40. Next, add a Vertically in Container constraint. Your final UI should look like the screenshot shown below.

Adding Gradient Colors Getting Started.png

Make it Gradient

Creating gradient is quite simple with CAGradientLayer, but there are few things you need to understand about it, and that is why you are here 😅. Let’s start by specifying the colors we will be using (you can modify them) and create an instance of CAGradientLayer.

Add a global property to check if the gradient is added to your button.

var isGradientAdded: Bool = false

Next, add the viewDidAppear(_:) function to your class as mentioned below.

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    if !isGradientAdded {

        let colors = [UIColor.red.cgColor, UIColor.green.cgColor, UIColor.blue.cgColor]

        let gradientLayer = CAGradientLayer()
        gradientLayer.colors = colors

        self.gradientButton.layer.insertSublayer(gradientLayer, at: 0)
    }
}

Now you may be wondering, the same result can be achieved in the viewDidLoad() function, the problem is AutoLayout, initializing UI with the geometry of other objects may give you incorrect values in the viewDidLoad() function, and trust me I am speaking with experience. One day it’s all running fine, and suddenly it breaks; the same goes for viewWillAppear(_:). The only place you should be accessing geometry related properties for initializing other objects is viewDidAppear(_:) and viewDidLayoutSubviews().

So we have added three colors (RGB), passed those colors into the CAGradientLayer object, and then inserted that layer into our button. Looks pretty good.

Now let’s run the app and see what happens.

Gradient Button.png

Nothing Gradient about it.

The problem is CAGradientLayer doesn’t know the size of it, nor we specified it. Let’s fix this.

gradientLayer.colors = colors
gradientLayer.frame = self.gradientButton.bounds // New line

Note: Only add the lines with a New line comment on it. Now let’s rerun the app.

Gradient Added Button.png

Not so pretty! By default, the gradient layer will give us a vertical gradient with the colors distributed equally. We can alter both of them. Let’s start by changing the alignment.

The colors are aligned vertically, so to make them horizontal; we need to rotate our layer by 90 degrees or 270 degrees. Rotating 90 degrees will flip our color. So I’ll go with 270. You can modify it to 90 if you like.

gradientLayer.colors = colors
gradientLayer.transform = CATransform3DMakeRotation(270 / 180 * CGFloat.pi, 0, 0, 1) // New line
gradientLayer.frame = self.gradientButton.bounds

Note: gradientLayer.frame should be set after the transform is done.

To rotate the layer, we need to covert 270 degrees into radians, and for that, we are executing an expression in our first argument.

Rerun the app

Gradient Horizontal.png

Bonus

The location at which the colors are located in a gradient can be modified. Let’s look at how it’s done.

gradientLayer.transform = CATransform3DMakeRotation(270 / 180 * CGFloat.pi, 0, 0, 1)
gradientLayer.locations = [0.0, 0.3, 0.7] // New line
gradientLayer.frame = self.gradientButton.bounds

Run the app, and the location of the colors should be different now.

Gradient Location.png

I hope you guys liked the article. Please subscribe to keep me motivated 😉 and to receive weekly updates. I’ll be posting my articles every Tuesday. That will be the day you’ll have to open your Inbox for me. Also, feel free to share your experience with me on Twitter or on Discord.

Download the final project here.

Custom Transition in Swift with present view controller - Non-interactive