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.
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 theviewDidLoad()
function, and trust me I am speaking with experience. One day it’s all running fine, and suddenly it breaks; the same goes forviewWillAppear(_:)
. The only place you should be accessing geometry related properties for initializing other objects isviewDidAppear(_:)
andviewDidLayoutSubviews()
.
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.
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.
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
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.