Cheat Sheet for UIBezierPath, CGPath and Path

Luiz Pedro Franciscatto Guerra
2 min readAug 1, 2022

--

This article’s banner, written in the center: “Cheat Sheet — for UIBezierPat, CGPath and Path — UIKit and SwiftUI”
Part 5/5! We did it!

If you have already developed using UIBezierPath, CGPath, or Path, and haven't been fiddling with them for quite some time, this might help you.

This article will showcase how to write a "D" shape (see next image), showing how to write a line and a bezier curve for each technology.

A simple "D" shaped image
Orange "D" shape

UIBezierPath

This way of drawing allows you to abstract the drawing into a CAShapeLayer

The text in bold is the setup (boilerplate) of colors and layering (since you might be here to remember how to set up the code):

func drawDShape() -> CAShapeLayer {
let shapeLayer = CAShapeLayer()
shapeLayer.position = self.view.center

shapeLayer.fillColor = UIColor.white.cgColor
shapeLayer.lineWidth = 5
shapeLayer.strokeColor = UIColor.orange.cgColor


let bezierPath = UIBezierPath()
bezierPath.move(to: .zero)
bezierPath.addCurve(
to: CGPoint(x: 0, y: 100),
controlPoint1: CGPoint(x: 75, y: 0),
controlPoint2: CGPoint(x: 75, y: 100))
bezierPath.addLine(to: .zero)
bezierPath.close()
shapeLayer.path = bezierPath.cgPath
return shapeLayer
}

CGPath

This way of drawing allows you to abstract the drawing elements into a separate UIView.

The text in bold is the setup (boilerplate) of colors and context (since you might be here to remember how to set up the code):

class DShapeView: UIView {
override func draw(_ rect: CGRect) {
guard let context = UIGraphicsGetCurrentContext() else {
return
}
context.saveGState()
defer {
context.restoreGState()
}


context.beginPath()
context.move(to: .zero)
context.addCurve(
to: CGPoint(x: 0, y: rect.height),
control1: CGPoint(x: rect.width * 0.75, y: 0),
control2: CGPoint(x: rect.width * 0.75, y: rect.height))
context.addLine(to: .zero)
context.closePath()
context.setFillColor(UIColor.white.cgColor)
context.setStrokeColor(UIColor.orange.cgColor)
context.setLineWidth(5)

context.strokePath()
context.fillPath()
}
}

SwiftUI's Path

You can draw either by creating a Shape struct or using the Path view in the body code.

The text in bold is the drawing code, everything else is boilerplate:

struct DShapeView: View {
var body: some View {
DShape()
.stroke(Color.orange, lineWidth: 5)
.frame(width: 100, height: 100)
.offset(x: 25, y: -50)
}
}
struct DShape: Shape {
func path(in rect: CGRect) -> Path {
Path { path in
path.move(to: .zero)
path.addCurve(
to: CGPoint(x: 0, y: rect.height),
control1: CGPoint(x: rect.width*0.75, y: 0),
control2: CGPoint(x: rect.width*0.75, y: rect.height))
path.addLine(to: .zero)
path.closeSubpath()

}
}
}

If you want me to add something here or ask anything, feel free to comment here or send me a message on Twitter. You can access those 3 code examples with commented code and more on my GitHub.

--

--

Luiz Pedro Franciscatto Guerra

Software Engineer, native iOS and Flutter developer. I also enjoy learning about design, security, code smells and machine learning. He/him