How to draw a smooth circle with CAShapeLayer and UIBezierPath?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
CAShapeLayer and UIBezierPath are the standard tools for drawing smooth vector circles on iOS. They render more cleanly than bitmap images, scale well across device sizes, and are easy to animate.
The basic idea is to create a circular path, assign it to a shape layer, and make sure the layer's geometry matches the final layout. Most "rough circle" problems come from sizing or stroke placement, not from the path API itself.
Create a Circular Path
The easiest way to create a circle is to use UIBezierPath(ovalIn:) with a square rectangle:
If the rectangle is square, the oval is a circle. If it is not square, the result is an ellipse. That is the first rule: if you want a circle, keep the geometry square.
Render the Path with CAShapeLayer
Once the path exists, assign it to a shape layer:
contentsScale helps the layer render crisply on Retina displays. It is often already correct, but setting it explicitly is a reasonable safeguard in custom drawing code.
Update the Circle After Layout
In real UI code, the path should usually be created after the view has its final bounds. A small view subclass makes this straightforward:
The inset is important because the stroke is centered on the path. Without it, part of a thick stroke can be clipped at the edge of the layer.
Keep the Result Smooth
A vector circle drawn this way should already look smooth. If it does not, the common causes are:
- the drawing rect is not square
- the path was created before final layout
- the stroke is being clipped
- the layer is being scaled awkwardly after drawing
That is why layout usually matters more than "Bezier smoothness" for circles. The APIs already produce mathematically smooth curves.
Common Pitfalls
The biggest mistake is drawing the path in a non-square rectangle and expecting a perfect circle.
Another common issue is forgetting stroke alignment. If the path touches the bounds exactly, a thick stroke can be clipped unless you inset the drawing rect by half the line width.
It is also easy to build the path too early, before Auto Layout has sized the view, which produces incorrect geometry.
Finally, if the circle looks blurry, check scaling and layout first. A CAShapeLayer drawing a proper circle path should look crisp when the geometry is correct.
Summary
- Use
UIBezierPath(ovalIn:)with a square rect to create a circle. - Assign the path to a
CAShapeLayerfor crisp vector rendering. - Inset the drawing rect by half the line width to avoid clipping.
- Build or update the path after layout so the bounds are final.
- Circle quality problems usually come from geometry, not from the drawing APIs.

