iOS draw filled Circles
Asked Answered
D

5

36

Not a graphics programmer here, so I'm trying to stumble through this. I'm trying to draw 9 filled circles, each a different color, each with a white border. The UIView's frame is CGRectMake (0,0,60,60). See attached image.

The problem is I'm getting "flat spots" on the borders on each side. Following is my code (from the UIView subclass):

- (void)drawRect:(CGRect)rect
{
    CGRect borderRect = CGRectMake(0.0, 0.0, 60.0, 60.0);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0);
    CGContextSetRGBFillColor(context, colorRed, colorGreen, colorBlue, 1.0);
    CGContextSetLineWidth(context, 2.0);
    CGContextFillEllipseInRect (context, borderRect);
    CGContextStrokeEllipseInRect(context, borderRect);
    CGContextFillPath(context);
}

If I change to CGRectMake(0,0,56,56) in drawRect, I get flat spots only on the top and left sides, and the bottom & right sides look fine.

Can anyone suggest how I might fix this? It seems to me the border is being clipped by the UIView, but not knowing much about this, I really don't know how to fix it.

Thanks, in advance, for any of you graphics experts' suggestions.

enter image description here

Dogvane answered 11/6, 2013 at 6:45 Comment(1)
Thanks for sharing the code. Btw. I think CGContextFillPath(context);is not needed.Castanets
A
38

I like the answer from @AaronGolden, just wanted to add:

CGRect borderRect = CGRectInset(rect, 2, 2);

Or, better:

CGFloat lineWidth = 2;
CGRect borderRect = CGRectInset(rect, lineWidth * 0.5, lineWidth * 0.5);
Awed answered 11/6, 2013 at 7:9 Comment(1)
@JohnRiselvato I cant figure out why this gives me a view with a black background?Gerundive
R
18

Those circles are just getting clipped to the bounds of the views that draw them. The views must be slightly larger than the circles to be drawn. You can imagine the CGContextStrokeEllipseInRect call tracing a circle of radius 30 and then painting one pixel on each side of the traced curve. Well on the far edges you're going to have one of those pixels just outside the boundary of the view.

Try making your views something like 62x62, or make the circle radius slightly smaller to leave room for the thick stroke in your 60x60 views.

Radiocommunication answered 11/6, 2013 at 7:3 Comment(1)
Thanks for your reply. Same answer but since Wain's had the code I just grabbed it and worked perfectly.Dogvane
D
7

I Wrote this so that you can draw many circles easily.

Add the following code to your .m file:

- (void) circleFilledWithOutline:(UIView*)circleView fillColor:(UIColor*)fillColor outlineColor:(UIColor*)outlinecolor{
CAShapeLayer *circleLayer = [CAShapeLayer layer];
float width = circleView.frame.size.width;
float height = circleView.frame.size.height;
[circleLayer setBounds:CGRectMake(2.0f, 2.0f, width-2.0f, height-2.0f)];
[circleLayer setPosition:CGPointMake(width/2, height/2)];
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(2.0f, 2.0f, width-2.0f, height-2.0f)];
[circleLayer setPath:[path CGPath]];
[circleLayer setFillColor:fillColor.CGColor];
[circleLayer setStrokeColor:outlinecolor.CGColor];
[circleLayer setLineWidth:2.0f];
[[circleView layer] addSublayer:circleLayer];
}

Then Add the following code to your view did load and replace "yourView" with any view that you want to place the circle in. If you want to make a bunch of circles just add some small views to the page and repeat the code below. The circle will become the size of the view you make.

[self circleFilledWithOutline:self.yourView fillColor:[UIColor redColor] outlineColor:[UIColor purpleColor]];
Decontaminate answered 27/6, 2015 at 0:7 Comment(0)
S
7

There is a simple way to draw a fill circle

CGContextFillEllipseInRect(context, CGRectMake(x,y,width,height))
Slipper answered 25/11, 2015 at 3:35 Comment(0)
P
4

Trianna Brannon's answer on Swift 3

func circleFilledWithOutline(circleView: UIView, fillColor: UIColor, outlineColor:UIColor) {
    let circleLayer = CAShapeLayer()
    let width = Double(circleView.bounds.size.width);
    let height = Double(circleView.bounds.size.height);
    circleLayer.bounds = CGRect(x: 2.0, y: 2.0, width: width-2.0, height: height-2.0)
    circleLayer.position = CGPoint(x: width/2, y: height/2);
    let rect = CGRect(x: 2.0, y: 2.0, width: width-2.0, height: height-2.0)
    let path = UIBezierPath.init(ovalIn: rect)
    circleLayer.path = path.cgPath
    circleLayer.fillColor = fillColor.cgColor
    circleLayer.strokeColor = outlineColor.cgColor
    circleLayer.lineWidth = 2.0
    circleView.layer.addSublayer(circleLayer)
}

And invoke func via:

self.circleFilledWithOutline(circleView: myCircleView, fillColor: UIColor.red, outlineColor: UIColor.blue)
Polanco answered 24/11, 2016 at 13:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.