zealoushacker
zealoushacker

Reputation: 6906

What is the best technique to render circles in iOS?

When rendering opaque non-gradient circular shapes of uniform color in iOS, there seem to be three possible techniques:

Using images like circle-icon.png and [email protected]. Then, one may implement the following code to have iOS automagically render the appropriate size:

UIImage *image = [UIImage imageNamed:@"circle-icon"];
self.closeIcon = [[UIImageView alloc] initWithImage:image];
self.closeIcon.frame = CGRectMake(300, 16, image.size.width, image.size.height);

Rendering rounded corners and using layers, like so:.

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

Using the native drawing libraries, with something like CGContextFillEllipseInRect

What are the exact performance and maintenance tradeoffs of these 3 approaches?

Upvotes: 4

Views: 1008

Answers (3)

Rob
Rob

Reputation: 437492

You're overlooking another very logical alternative, UIBezierPath and CAShapeLayer. Create UIBezierPath that is a circle, create a CAShapeLayer that uses that UIBezierPath, and then add that layer to your view/layer hierarchy.

  1. Add the QuartzCore framework to your project.

  2. Second, import the appropriate header:

    #import <QuartzCore/QuartzCore.h>
    
  3. And then you can add a CAShapeLayer to your view's layer:

    UIBezierPath *path = [UIBezierPath bezierPath];
    [path addArcWithCenter:CGPointMake(self.view.bounds.size.width / 2.0, self.view.bounds.size.height / 2.0) radius:self.view.bounds.size.width * 0.40 startAngle:0 endAngle:M_PI * 2.0 clockwise:YES];
    CAShapeLayer *layer = [[CAShapeLayer alloc] init];
    layer.path = [path CGPath];
    layer.fillColor = [[UIColor blueColor] CGColor];
    [self.view.layer addSublayer:layer];
    

I think that either a CoreGraphics implementation, or this CAShapeLayer implementation make more sense than PNG files or UIView objects with rounded corners.

Upvotes: 3

HalR
HalR

Reputation: 11073

The sharpest and best looking result is to have a well drawn image that is exactly the size you want the circle to be. If you are sizing the circles, you will often not get the look you want, and there is some overhead associated with them.

I think your best performance for cleanliness and speed would come from using core graphics and its add ellipse in a square:

CGPathRef roundPath = CGPathCreateMutable();       
CGRect rectThatIsASquare = CGRectMake(0, 0, 40, 40);
CGPathAddEllipseInRect(roundPath, NULL, rectThatIsASquare);
CGContextSetRGBFillColor(context, 0.7, 0.6, 0.5, 1.0);

CGContextFillPath(context);

Upvotes: 3

Lawrence H
Lawrence H

Reputation: 467

Personally, I think you are over-thinking the problem. If you're only drawing a few circles, there is going to be very very little performance/maintenance impact whichever you decide on, and even if you optimize it to hell your users aren't getting any benefits from it. Do whatever you're doing now; focus on making the app's content great, and come back to performance later on if you really need to.

With that being said, I would recommend using drawing libraries.

  1. Rounding corners is slow and rather non-intuitive
  2. Using image files will be a problem if you decide to do stuff like change colors. Also, sometimes images don't look that great after you scale them.

Upvotes: 1

Related Questions