# Core Graphics Tutorial: Arcs and Paths

**Swift 4.2, iOS 12, Xcode 10**Swift 4.2, iOS 12, Xcode 10

In this tutorial, you’ll learn how to draw arcs and paths. In particular, you’ll enhance each footer of a grouped table view by adding a neat arc on the bottom, a linear gradient and a shadow that fits the curve of the arc. All of that by using the power of Core Graphics! By Lorenzo Boaro.

### Sign up/Sign in

With a **free** Kodeco account you can download source code, track your progress,
bookmark, personalise your learner profile and more!

Already a member of Kodeco? Sign in

### Sign up/Sign in

With a **free** Kodeco account you can download source code, track your progress,
bookmark, personalise your learner profile and more!

Already a member of Kodeco? Sign in

### Sign up/Sign in

With a **free** Kodeco account you can download source code, track your progress,
bookmark, personalise your learner profile and more!

Already a member of Kodeco? Sign in

## Contents

## Core Graphics Tutorial: Arcs and Paths

20 mins

*Update note*: Lorenzo Boaro updated this tutorial for iOS 12, Xcode 10 and Swift 4.2. Ray Wenderlich wrote the original.

Welcome back to another tutorial in our Core Graphics tutorial series! This series covers how to get started with Core Graphics. Core Graphics is a two-dimensional drawing engine with path-based drawing that helps you to create rich UIs.

In this tutorial, you’ll learn how to draw arcs and paths. In particular, you’ll enhance each footer of a grouped table view by adding a neat arc on the bottom, a linear gradient and a shadow that fits the curve of the arc. All of that by using the power of Core Graphics!

## Getting Started

For this tutorial, you’ll use *LearningAgenda*, an iOS app that lists the tutorials you want to learn and the ones you’ve already learned.

Start by downloading the starter project using the *Download Materials* button at the top or bottom of this tutorial. Once downloaded, open *LearningAgenda.xcodeproj* in Xcode.

To keep you focused, the starter project has everything unrelated to arcs and paths already set up for you.

Build and run the app, and you’ll see the following initial screen:

As you can see, there is a grouped table consisting of two sections, each with a title and three rows. All the work you’re going to do here will create arced footers below each section.

## Enhancing the Footer

Before taking on your challenge, you need to create and set up a custom footer that will behave as the placeholder for your future work.

To create the class for your shiny new footer, right-click the *LearningAgenda* folder and select *New File*. Next, choose *Swift File* and name the file *CustomFooter.swift*.

Switch over to *CustomFooter.swift* file and replace its content with the following code:

```
import UIKit
class CustomFooter: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
isOpaque = true
backgroundColor = .clear
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func draw(_ rect: CGRect) {
let context = UIGraphicsGetCurrentContext()!
UIColor.red.setFill()
context.fill(bounds)
}
}
```

Here, you override `init(frame:)`

to set `isOpaque`

true. You also set the background color to clear.

*Note*: The

`isOpaque`

property should not be used when the view is fully or partially transparent. Otherwise, the results could be unpredictable.You also override `init?(coder:)`

since it’s mandatory, but you don’t provide any implementation since you will not create your custom footer in Interface Builder.

`draw(_:)`

provides a custom rect content using Core Graphics. You set red as the fill color to cover the entire bounds of the footer itself.

Now, open *TutorialsViewController.swift* and add the following two methods to the `UITableViewDelegate`

extension at the bottom of the file:

```
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 30
}
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
return CustomFooter()
}
```

The above methods combine to form a custom footer of 30 points in height.

Build and run the project and, if all works well, you should see the following:

### Back to Business

OK, now that you have a placeholder view in place, it’s time to pretty it up. But first, here’s an idea of what you’re going for.

Note the following about the image above:

- The footer has a neat arc on the bottom.
- A gradient, from light gray to darker gray, is applied to the footer.
- A shadow fits the curve of the arc.

### The Math Behind Arcs

An arc is a curved line that represents a part of a circle. In your case, the arc you want for the bottom of the footer is the top bit of a very large circle, with a very large radius, from a certain start angle to a certain end angle.

So how do you describe this arc to Core Graphics? Well, the API that you’re going to use is called `addArc(center:radius:startAngle:endAngle:clockwise:)`

, an instance method of `CGContext`

. The method expects the following five inputs:

- The center point of the circle.
- The radius of the circle.
- The starting point of the line to draw, also know as the start angle.
- The ending point of the line to draw, also known as the end angle.
- The direction in which the arc is created.

But darn it, you don’t know any of that, so what in the world are you supposed to do?!

That is where some simple math comes to the rescue. You can actually calculate all of that from what you do know!

The first thing you know is the size of the bounding box for where you want to draw the arc:

The second thing you know is an interesting math theorem called the Intersecting Chord Theorem. Basically, this theorem states that, if you draw two intersecting chords in a circle, the product of the line segments of the first chord will be equal to the product of the segments of the second chord. Remember, a chord is a line that connects two points in a circle.

*Note*: If you want to understand why that is, visit the link above — it has a cool little JavaScript demo you can play with.

Armed with these two bits of knowledge, look what happens if you draw two chords like the following:

So, draw one line connecting the bottom points of your arc rect and another line from the top of the arc down to the bottom of the circle.

If you do that, you know *a*, *b*, and *c*, which lets you figure out *d*.

So *d* would be: *(a * b) / c*. Substituting that out, it’s:

```
// Just substituting...
let d = ((arcRectWidth / 2) * (arcRectWidth / 2)) / (arcRectHeight);
// Or more simply...
let d = pow(arcRectWidth, 2) / (4 * arcRectHeight);
```

And now that you know *c* and *d*, you can calculate the radius with the following formula: *(c + d) / 2*:

```
// Just substituting...
let radius = (arcRectHeight + (pow(arcRectWidth, 2) / (4 * arcRectHeight))) / 2;
// Or more simply...
let radius = (arcRectHeight / 2) + (pow(arcRectWidth, 2) / (8 * arcRectHeight));
```

Nice! Now that you know the radius, you can get the center by simply subtracting the radius from the center point of your shadow rect:

```
let arcCenter = CGPoint(arcRectTopMiddleX, arcRectTopMiddleY - radius)
```

Once you know the center point, radius and arc rect, you can compute the start and end angles with a bit of trigonometry:

You’ll start by figuring out the angle shown in the diagram, here. If you remember *SOHCAHTOA*, you might recall the cosine of an angle equals the length of the adjacent edge of the triangle divided by the length of the hypotenuse.

In other words, `cosine(angle) = (arcRectWidth / 2) / radius`

. So, to get the angle, you simply take the arc-cosine, which is the inverse of the cosine:

```
let angle = acos((arcRectWidth / 2) / radius)
```

And now that you know that angle, getting the start and end angles should be rather simple:

Nice! Now that you understand how, you can put it all together as a function.

*Note*: By the way, there’s actually an even easier way to draw an arc like this using the

`addArc(tangent1End:tangent2End:radius:)`

method available in `CGContext`

type.