Canvas draws 2D graphics in immediate mode, line by line, instead of composing Shape views
that SwiftUI must render individually. Reach for it when a drawing is too rich or too dense for
the view tree.
The Renderer
The trailing closure is the renderer. It receives a GraphicsContext and the canvas size, and
the context is inout, so state you set affects everything drawn after that line.
Canvas(opaque: true, colorMode: .linear, rendersAsynchronously: false) { context, size in
context.opacity = 0.3
let rect = CGRect(origin: .zero, size: size)
context.fill(Circle().path(in: rect), with: .color(.red))
let inner = rect.applying(.init(scaleX: 0.5, y: 0.5))
context.fill(Circle().path(in: inner), with: .color(.red))
}
The context exposes fill, stroke, and clip for paths, plus opacity, scaling, blend mode,
and addFilter for effects.
Drawing Text, Images, and Views
Text and Image cannot be drawn directly. Resolve them first; the resolved value exposes
shading you can tune before draw.
let text = Text(verbatim: "Hello").font(.largeTitle)
var resolvedText = context.resolve(text)
resolvedText.shading = .color(.red)
context.draw(resolvedText, in: rect)
Arbitrary SwiftUI views go through the symbols closure. Tag each view, then look it up by id
in the renderer.
Canvas { context, size in
let rect = CGRect(origin: .zero, size: size)
if let symbol = context.resolveSymbol(id: 1) {
context.draw(symbol, in: rect)
}
} symbols: {
Text(verbatim: "Hello")
.foregroundColor(.red)
.tag(1)
}
Animation
Canvas does not animate on its own. Wrap it in TimelineView(.animation) and derive drawing
parameters from the timeline date.
TimelineView(.animation) { timelineContext in
let value = secondsValue(for: timelineContext.date)
Canvas { context, size in
let newSize = size.applying(.init(scaleX: value, y: 1))
context.fill(Rectangle().path(in: .init(origin: .zero, size: newSize)),
with: .color(.red))
}
}
Accessibility
A canvas has no accessibility tree, it is raw graphics. Attach the standard accessibility
modifiers to the Canvas itself to describe what it shows.