In this article I am going to show how to add a gradient to any view without protocols. In it we will use CAGradientLayer to draw the gradient; An extension of CALayer for finding the created layer so we can skip the assignment to a property; And an UIView extension for using and customizing the gradient.
We are going to start by adding the CALayer extension to find our gradient layer later on:
As you can see we are adding an additional method to CALayer that will search the sublayers of it. We are using the name variable that is present in CALayer. We are just going through all sublayers and checking if there is a name match. Keep in mind that this method will give us the first match of the name and it needs to be exact, even the casing.
Next we need to crate the extension of UIView and start drawing the gradient. For it we will need a constant for the name of the gradient. We can achieve that by making a private structure in our extension, because it will only be used inside it.
Now the making of the CAGradientLayer:
We are implementing just a getter for the gradientLayer which will give us the gradient layer that already exists or, if not, create it and return it. Here on creation, we are just setting the basics like:
The frame of the gradient which will fill the whole view in which we are going to add it, so we are setting its frame to the bounds of the UIView;
The name of the layer. This is needed to find it later on;
The starting point in the gradient. By default it will be (0, 0) which is the top left corner of the view, in Swift we are passing it as CGPoint.zero;
The z position, so it will be always below all other layers;
This shouldRasterize variable which will rasterize the drawn gradient every time it is changed. You can make it as a variable in the extension if you want, but I need it as a vector because I use a lot of scale animations in my project and if it is raster it will just pixelize for no reason;
And add our gradient layer to the main layer of the view.
It is time to add some getters and setters so we can customize the gradient however we like. We will start with the colors that will construct the gradient.
This is a getter and setter because sometimes we would need to check if we are working with the correct gradient. I prefer to work with the UI components so I do convert them to CGColor. This allows me to use the colors that I added in my .xcassets catalogue. The colors passed to this setter will be converted to CGColor and passed to the gradientLayer where they will be evenly distributed to make a beautiful gradient.
The last property that I want to change is the ending point of the gradient draw. You can pass it as CGPoint and also make a variable for the starting point which will allow you to draw diagonal gradients as well but I need them to be just vertical or horizontal. To make that I am going to add an enum for that.
If we want a horizontal gradient we just pass end point (1, 0) to the gradientLayer and as we have starting point when we created it of (0, 0) it will be drawn on the x axis. If we want a vertical gradient we just pass the point (0, 1).
How do we use it? It is super simple, just create your UIView or subclass of it like a UIButton and pass the colors and direction that you want for the gradient: