How to draw a custom UIView that is just a circle - iPhone app

151,059

Solution 1

You could use QuartzCore and do something this --

self.circleView = [[UIView alloc] initWithFrame:CGRectMake(10,20,100,100)];
self.circleView.alpha = 0.5;
self.circleView.layer.cornerRadius = 50;  // half the width/height
self.circleView.backgroundColor = [UIColor blueColor];

Solution 2

Would I just override the drawRect method?

Yes:

- (void)drawRect:(CGRect)rect
{
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextAddEllipseInRect(ctx, rect);
    CGContextSetFillColor(ctx, CGColorGetComponents([[UIColor blueColor] CGColor]));
    CGContextFillPath(ctx);
}

Also, would it be okay to change the frame of that view within the class itself?

Ideally not, but you could.

Or do I need to change the frame from a different class?

I'd let the parent control that.

Solution 3

Here is another way by using UIBezierPath (maybe it's too late ^^) Create a circle and mask UIView with it, as follows:

UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
view.backgroundColor = [UIColor blueColor];

CAShapeLayer *shape = [CAShapeLayer layer];
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:view.center radius:(view.bounds.size.width / 2) startAngle:0 endAngle:(2 * M_PI) clockwise:YES];
shape.path = path.CGPath;
view.layer.mask = shape;

Solution 4

My contribution with a Swift extension:

extension UIView {
    func asCircle() {
        self.layer.cornerRadius = self.frame.width / 2;
        self.layer.masksToBounds = true
    }
}

Just call myView.asCircle()

Solution 5

Swift 3 - custom class, easy to reuse. It uses backgroundColor set in UI builder

import UIKit

@IBDesignable
class CircleBackgroundView: UIView {

    override func layoutSubviews() {
        super.layoutSubviews()
        layer.cornerRadius = bounds.size.width / 2
        layer.masksToBounds = true
    }

}
Share:
151,059
StanLe
Author by

StanLe

Updated on July 08, 2022

Comments

  • StanLe
    StanLe almost 2 years

    How would I go about drawing a custom UIView that is literally just a ball (a 2D circle)? Would I just override the drawRect method? And can someone show me the code for drawing a blue circle?

    Also, would it be okay to change the frame of that view within the class itself? Or do I need to change the frame from a different class?

    (just trying to set up a ball bouncing around)

  • Benjamin Mayo
    Benjamin Mayo almost 13 years
    FYI, in order for your view to be a circle using QuartCore, your corner radius needs to be half your frame height/width. This is the easiest way of making a circle, but is not necessarily the most efficient. If performance is vital, drawRect will probably yield better results.
  • Kal
    Kal almost 13 years
    And it is. 100 is the height/width.
  • Benjamin Mayo
    Benjamin Mayo almost 13 years
    Yeah, sorry wasn't directing that at you, Kal. I was mentioning that to StanLe in case he wanted to use different sized views.
  • gaussblurinc
    gaussblurinc almost 11 years
    How can I set custom colors, not only blue? I try to use white and blue like this: ([self.colorOfCircle CGColor]) but nothing happens :\
  • Steve
    Steve almost 11 years
    @loldop is self.colorOfCircle a UIColor? Is it set? If you put a breakpoint on that line and look at the value, is it what you're expecting? IF you set that after the fact, you'll have to invalidate the portion of your view that contains the circle.
  • yonilevy
    yonilevy over 10 years
    @gaussblurinc use CGContextSetFillColorWithColor(ctx, self.colorOfCircle.CGColor);, the method proposed in the solution CGColorGetComponents only works with some colors, see stackoverflow.com/questions/9238743/…
  • Max Steinmeyer
    Max Steinmeyer almost 10 years
    There's not really a need to make that shape layer a mask; you could just use the shape layer directly as the view's layer and give it a fill color. The mask is probably significantly more expensive.
  • Gintama
    Gintama almost 10 years
    UIView's layer is CALayer so how can we draw a shape on this layer. I suppose that we add shape layer to view's layer without masking it ??
  • Max Steinmeyer
    Max Steinmeyer almost 10 years
    You can subclass UIView and override the layerClass class method to make it a shape layer.
  • Olie
    Olie almost 10 years
    Note to anyone who gets themselves stuck on this. Rather than rect, I accidentally used self.frame for the ellipse. The correct value is self.bounds. D'oh! :)
  • gran33
    gran33 over 9 years
    If your circleView size isn't 100X100, the cornerRadius should be the (new size)/2
  • User
    User almost 9 years
    But I noticed that circle with cornerradius has sometimes slightly "flat"/clipped edges. At least when used with a border. Any idea why? The radius is exactly half of view's size. I thought it may be clipping issue, but doesn't seem like that, tried even with a smaller sublayer - still have the same effect.
  • Nik
    Nik almost 9 years
    @Ixx maybe you have to override - (void)drawRect if you want to make it look better...
  • User
    User almost 9 years
    @dig I was aware that that is possible... ended doing that and yes, that looks correct. Was just curious if there was a fix using corner radius. Set clip bounds to false also didn't help.
  • Richard Venable
    Richard Venable almost 8 years
    @JesseRusak, the problem I'm having with your suggestion (to set the shape on the UIView's layer itself) is that you have to can't properly use the backgroundColor. You would need to apply a fillColor and set the backgroundColor to clearColor, which means a user of the UIView would not be able to naturally set the backgroundColor.
  • Max Desiatov
    Max Desiatov about 7 years
    setting masksToBounds to true and using self are all optional in this answer, but it's still the shortest and best solution