Custom Drawing with Core Graphics
Draw paths and shapes in draw(_:).
Custom Drawing with Core Graphics is a free Swift Academy lesson on CoddyKit. This is lesson 4 of 4. Any 3 lessons of this learning path are free to read in full — after that, CoddyKit PRO unlocks every lesson, plus hands-on practice with a built-in code editor and a 24/7 AI tutor. It is part of the Swift Academy learning path, and your progress syncs across the web and the CoddyKit app. The Swift Academy course includes 4 lessons in total.
When to Draw Custom Content
When layers and images cannot express a shape—charts, signatures, custom controls—you draw it yourself with Core Graphics (Quartz 2D).
Overriding draw(_:)
Subclass UIView and override draw(_:). UIKit calls it with a configured context; you issue drawing commands there.
import UIKit
final class ChartView: UIView {
override func draw(_ rect: CGRect) {
// drawing commands go here
}
}The Graphics Context
Inside draw(_:), get the current CGContext. It is a stateful canvas: you set colors and line widths, then stroke or fill.
override func draw(_ rect: CGRect) {
guard let ctx = UIGraphicsGetCurrentContext() else { return }
ctx.setFillColor(UIColor.systemTeal.cgColor)
ctx.fill(rect)
}Building Paths
A CGPath (or UIBezierPath) describes lines, curves, and shapes. Move to a start point, then add lines and curves.
let path = UIBezierPath()
path.move(to: CGPoint(x: 0, y: 0))
path.addLine(to: CGPoint(x: 100, y: 50))
path.addLine(to: CGPoint(x: 0, y: 100))
path.close()Stroking and Filling
Strokes outline a path; fills color its interior. Set the color and width, then call stroke() or fill().
UIColor.systemRed.setStroke()
let line = UIBezierPath()
line.lineWidth = 3
line.move(to: CGPoint(x: 10, y: 10))
line.addLine(to: CGPoint(x: 90, y: 90))
line.stroke()Curves
Add smooth curves with quadratic (addQuadCurve) or cubic (addCurve) Bezier segments, specifying control points.
let p = UIBezierPath()
p.move(to: CGPoint(x: 0, y: 100))
p.addCurve(to: CGPoint(x: 200, y: 100),
controlPoint1: CGPoint(x: 50, y: 0),
controlPoint2: CGPoint(x: 150, y: 200))Context State: Save and Restore
The context is stateful. Wrap transforms and clipping in saveGState()/restoreGState() so changes do not leak into later drawing.
ctx.saveGState()
ctx.translateBy(x: 50, y: 50)
ctx.rotate(by: .pi / 4)
// draw rotated content
ctx.restoreGState()Gradients and Shadows
Core Graphics draws gradients (CGGradient with drawLinearGradient) and shadows (setShadow(offset:blur:color:)) directly into the context.
ctx.setShadow(offset: CGSize(width: 0, height: 2),
blur: 4,
color: UIColor.black.cgColor)Clipping
Add a path and call clip() to confine subsequent drawing to that region—useful for rounded images or masked fills.
let clipPath = UIBezierPath(ovalIn: rect)
clipPath.addClip()
// drawing now constrained to the ovalPerformance and setNeedsDisplay
draw(_:) runs on the CPU and is relatively costly. Trigger redraws only when needed via setNeedsDisplay(), and keep drawing code lean.
func updateData() {
self.data = newData
setNeedsDisplay() // schedule one redraw
}Off-Screen Rendering
For reusable bitmaps, render into an image with UIGraphicsImageRenderer instead of redrawing every frame.
let renderer = UIGraphicsImageRenderer(size: CGSize(width: 100, height: 100))
let image = renderer.image { ctx in
UIColor.systemBlue.setFill()
ctx.fill(CGRect(x: 0, y: 0, width: 100, height: 100))
}Quick Check: Core Graphics
Test your understanding of custom drawing.
Recap: Custom Drawing with Core Graphics
Override draw(_:) and issue commands to the CGContext: build paths with lines and Bezier curves, then stroke or fill. Isolate transforms and clipping with saveGState()/restoreGState(), and add gradients, shadows, and clips directly.
Drawing is CPU work—redraw only via setNeedsDisplay() and cache reusable bitmaps with UIGraphicsImageRenderer.
Learn Swift with an AI tutor — free
Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.
- Courses
- 122
- Lessons
- 409
Frequently Asked Questions
Is the “Custom Drawing with Core Graphics” lesson free?
Yes — any 3 lessons of the Swift Academy learning path, including “Custom Drawing with Core Graphics”, are free to read in full here on the web. After that, CoddyKit PRO unlocks every lesson, plus interactive practice with a built-in code editor and a 24/7 AI tutor. The Swift Academy course includes 4 lessons in total.
What will I learn in “Custom Drawing with Core Graphics”?
Draw paths and shapes in draw(_:). You practise Swift Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Swift Academy?
No prior experience is required. Swift Academy on CoddyKit is structured for beginners through advanced learners, so you can start here or from the beginning and move at your own pace. This is lesson 4 of 4.
How long does the “Custom Drawing with Core Graphics” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Swift Academy lesson?
Yes. Every Swift Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- CALayer Fundamentals
- Implicit and Explicit Animations
- Transforms and 3D Effects
- Custom Drawing with Core Graphics