Drawing using CAShapeLayer in iOS
You must have always wondered how to create different figures & shapes in iOS. Creating a rectangle and circle is easy, every view is itself a rectangle and if you ever want to create a circle you can use cornerRadius
property. But what about complex shapes? How can we create a triangle which has a weird shape inside it? It is all possible CAShapeLayer
We will start by learning how to create simple figures using UIBezierPath
and CAShapeLayer
, and move on to creating masks and complex figures using the same two things.
Basic shapes & figures
Every view in iOS has a CALayer
with it which can be used to add multiple customised layer inside it. It works similar to any UIView
, we can have a parent view and add multiple child views inside it. Similarly iOS provides us with a parent layer for every view and we will create separate layers for creating different shapes and then add that layer to the main layer.
Drawing a Rectangle
Output looks like this:
Let’s understand what all we did to achieve this.
- We have created a
containerView
on which we will draw our custom shapes. - Inside
drawRectangle
method we first create a path usingUIBezierPath
and then draw all the four side of a rectangle usingaddLine
method. Before adding all the lines we have used a methodmoveTo
which is used to point at the place where our path will start drawing. - After that we have created a new layer of type
CAShapeLayer
whose path is the custom path that we created above. We also assigned some colour properties and line width to make our rectangle look a bit nice. - At last we used the
containerView's
layer and added our layer to it as asubLayer
Drawing a Triangle
Output looks like this:
For creating a triangle there’s no magic. We have simply change the CGPoint
inside addLine
method to make it a rectangle.
Drawing an Oval/Circle
Output looks like this:
In this we didn’t create the path ourself. Swift provides us with some initialisers of UIBezierPath
which can be used to draw shapes for us. In this case we used UIBezierPath(ovalIn: <CGRect>)
, what it does is it takes a rectangle as an input and draws the biggest oval possible inside it. The height
and width
of our containerView
is same that is why it created a circle for us, if we increase the height
or width
then the resulting figure would be an oval.
Drawing an Arc
Output looks like this:
You will realise that we have used another initialiser for creating an arc using UIBezierPath
, we can also create a circle using this method. Let’s breakdown the initialiser and understand what are the different parameters that it takes.
UIBezierPath(arcCenter: <CGPoint>, radius: <CGFloat>, startAngle: <CGFloat>, endAngle: <CGFloat>, clockwise: <Bool>
arcCenter
-> This is the point from which the arc is drawn using it as a centre.radius
-> Radius of the arcstartAngle
-> The angle from which arc startsendAngle
-> The angle where arc endsclockwise
-> Whether the arc is drawn clockwise or not
Adding multiple layers
Recall that every view has a CALayer
and we can add many sublayers to it. In this section we are going to create a rectangle
which has circle
and triangle
inside it.
Three are four different methods by which we can insert a sublayer on to a layer:
addSublayer(<CALayer>)
-> This simply adds a new layer on the top of the stack of layersinsertSublayer(<CALayer>, at: <UInt32>
-> This method takes an extra parameterat
which inserts the layer at the given position inside the stack of layersinsertSublayer(<CALayer>, above: <CALayer?>
-> This method inserts the layer above a particular layerinsertSublayer(<CALayer>, below: <CALayer?>
-> This methods inserts the layer below a particular layer
Output looks like this:
Drawing a random shape
Let’s create a random shape using all the things that we have learnt so far.
Output looks like this:
Wrapping Up
This was all about getting started with CAShapeLayer in iOS. If you have any doubts then feel free to discuss in the comments.
Other article that you may like
Data Structures & Algorithms in Swift: Part 1 — Stack
Data Structures & Algorithms in Swift: Part 2 — Queue