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…