New in SwiftUI 3: Canvas

DevTechie
DevTechie
Published in
8 min readOct 19, 2021

--

SwiftUI 3 introduced a brand spanking new view called ✨ Canvas ✨ for rich and dynamic 2D graphics drawing.

Canvas view passes GraphicsContext and Size values to it closure which can be used to perform immediate mode drawing. Canvas can draw path, image, or complete SwiftUI views inside it.

Let’s take a look at Path drawing inside canvas:

struct SimpleCanvasExample: View {

var body: some View {
ZStack {
Canvas { context, size in
context.stroke(
Path(ellipseIn: CGRect(origin: .zero, size: size).insetBy(dx: 5, dy: 5)),
with: .color(.orange),
lineWidth: 4)
}
.frame(width: 300, height: 200)
.border(Color.blue)


Text("DevTechie")
.font(.largeTitle)
.foregroundColor(.orange)
}
}

}

Note use of context and size inside canvas closure in the code 👆

Here we are using Canvas’s closure to draw ellipse inside a CGRect. Note use of GraphicsContext to draw path for ellipse. We are also using size passed in closure to make sure that our ellipse fits well inside the rect.

Closure in Canvas is not a ViewBuilder like other closures in SwiftUI views, this one is a Swift closure so we can do Swift related operations directly inside the closure and draw on the GraphicsContext.

Lets create an example to perform additional Swifty 😃 operations inside Canvas closure.

struct SimpleCanvasExample: View {

var body: some View {
ZStack {
Canvas { context, size in

let gradient = Gradient(colors: [.blue, .pink, .orange])
let rect = CGRect(origin: .zero, size: size).insetBy(dx: 5, dy: 5)
let path = Path(ellipseIn: rect)

context.stroke(
path,
with: .color(.orange),
lineWidth: 10)

context.fill(path, with: .linearGradient(gradient, startPoint

--

--