user979331
user979331

Reputation: 11861

CGContextAddArc draw multiple circle at different sizes

I have these sizes that I want to draw a circle with (both width and height are the same obviously)

205.0
218.0
245.0
257.0
310.0
510.0

When I draw my circle at 205.5 its fine, its a perfect circle. But when I start with 218, the circle gets cut off a little and it gets more and more cut off each time I try to make a bigger circle. My question is, how do I create a circle that is perfect, no matter what the size ?

Here is my code:

func drawCircle()
{
    // Get the Graphics Context
    let context = UIGraphicsGetCurrentContext();

    // Set the circle outerline-width
    CGContextSetLineWidth(context, 5.0);

    // Set the circle outerline-colour
    UIColor.redColor().set()

    // Create Circle
    CGContextAddArc(context, (round(frame.size.width))/2, round(frame.size.height)/2, (round(frame.size.width) - 10)/2, 0.0, CGFloat(M_PI * 2.0), 1)

    // Draw
    CGContextStrokePath(context);
}

frame.size.width and frame.size.height are the numbers of 205, 218 and so on. I will accept an Objective-C answer.

Upvotes: 1

Views: 1549

Answers (2)

kennytm
kennytm

Reputation: 523234

If you want to draw a circle, use CGContext.addEllipse(in:) a.k.a. CGContextAddEllipseInRect instead of CGContextAddArc.

// swift 3:
let context = UIGraphicsGetCurrentContext()!
context.setLineWidth(5.0)
UIColor.red.set()

context.addEllipse(in: frame) // <--

context.strokePath()


// swift 2:
let context = UIGraphicsGetCurrentContext()
CGContextSetLineWidth(context, 5.0)
UIColor.redColor().set()

CGContextAddEllipseInRect(context, frame)  // <-- 

CGContextStrokePath(context)

Upvotes: 3

keithbhunter
keithbhunter

Reputation: 12324

The view you draw these in needs to be large enough to draw all of these circles in (so 510+ x 510+). You could set clipsToBounds = false to get around it, but that normally isn't a good idea.

UIBezierPath has a simple initializer for circle paths. You can use it to draw your circles and specify a radius.

// Use the center of the bounds of the view so we draw circles centered in our view.
// If you use self.center, this will be in the parent view's coordinate system and your circles could be off center.
CGPoint centerOfBounds = CGPointMake((self.bounds.origin.x + self.bounds.size.width) / 2, (self.bounds.origin.y + self.bounds.size.height) / 2);

// The startAngle, endAngle and clockwise don't matter much here since we are drawing a full circle.
// The only requirement is the start and end angle MUST be 2*PI apart.
UIBezierPath *two05 = [UIBezierPath bezierPathWithArcCenter:centerOfBounds radius:205.0/2, startAngle:0 endAngle:2*M_PI clockwise:false];
UIBezierPath *two18 = [UIBezierPath bezierPathWithArcCenter:centerOfBounds radius:218.0/2, startAngle:0 endAngle:2*M_PI clockwise:false];
UIBezierPath *two45 = [UIBezierPath bezierPathWithArcCenter:centerOfBounds radius:245.0/2, startAngle:0 endAngle:2*M_PI clockwise:false];
UIBezierPath *two57 = [UIBezierPath bezierPathWithArcCenter:centerOfBounds radius:257.0/2, startAngle:0 endAngle:2*M_PI clockwise:false];
UIBezierPath *three10 = [UIBezierPath bezierPathWithArcCenter:centerOfBounds radius:310.0/2, startAngle:0 endAngle:2*M_PI clockwise:false];
UIBezierPath *five10 = [UIBezierPath bezierPathWithArcCenter:centerOfBounds radius:510.0/2, startAngle:0 endAngle:2*M_PI clockwise:false];

// Set the color, line widths on the path, and call stroke on each bezier path to draw the circles
[[UIColor blueColor] setStroke];
two05.lineWidth = 1;
[two05 stroke];
// Reapeat for other paths...

Upvotes: 0

Related Questions