0

I want to position a UILabel in the center of my Circle but I can't seem to affect the position of the label. I can only seem to affect the position of the label by changing the height of CGRect frame. changing the other values doesn't affect the position at all.

here's my Circle.m code

- (id)initWithFrame:(CGRect)frame radius:(CGFloat)aRadius color:(UIColor*) aColor {
    self = [super initWithFrame:frame];
    if (self) {
        self.opaque = NO;

        [self setRadius:aRadius];
        [self setColor:aColor];
    }
    return self;
}


- (void)drawRect:(CGRect)rect
{

    NSString *string = @"1";
    UIFont* font = [UIFont systemFontOfSize:80];
    UILabel *label = [[UILabel alloc] init];
    label.text = string;
    label.textColor = [UIColor whiteColor];
    label.font = font;

    CGRect frame = label.frame;
    frame = CGRectMake(10, 10, 0, 85);
    label.frame = frame;

    CGContextRef contextRef = UIGraphicsGetCurrentContext();
    [color setFill];
    circle = CGRectMake(0, 0, radius, radius);

    CGContextAddEllipseInRect(contextRef, circle);
    CGContextDrawPath (contextRef, kCGPathFill);
    [label drawRect:circle];

}

and my viewController.m

- (void)viewDidLoad
{
    [super viewDidLoad];
    CGFloat radius = 70;
    CGRect position = CGRectMake(0, 0, radius, radius);
    Circle *myCircle = [[Circle alloc] initWithFrame:position radius:radius color:[UIColor redColor]];
    [self.view addSubview:myCircle];

}
Ramin Afshar
  • 989
  • 2
  • 18
  • 34
  • You do realize that a height of 0 doesn't show anything, right? – CodaFi Apr 07 '12 at 17:51
  • Agreed, 0 height of the label frame doesn't make sense. And also a little weird to see the frame of the circle with a width and height of `radius` because the diameter of the circle is at least twice that, right? And if you're going to do something simple like setting the label width to be twice the radius of the circle, you'd probably also want to make sure your label is using `[label setTextAlignment:UITextAlignmentCenter];`, correct? Just to make sure the text is center aligned within that frame? – Rob Apr 08 '12 at 03:37

1 Answers1

4

You should not be allocating new UIViews in drawRect: (and UILabel is a subclass of UIView). There are a few good ways of doing what you want, but none of them involve allocating a new UILabel in drawRect:.

One way is to make your Circle give itself a UILabel subview in its initializer, and center the label in layoutSubviews. Then in drawRect:, you just draw the circle and don't worry about drawing the label's text:

@implementation Circle {
    UILabel *_label;
}

@synthesize radius = _radius;
@synthesize color = _color;

- (id)initWithFrame:(CGRect)frame radius:(CGFloat)aRadius color:(UIColor*) aColor {
    self = [super initWithFrame:frame];
    if (self) {
        self.opaque = NO;

        [self setRadius:aRadius];
        [self setColor:aColor];

        _label = [[UILabel alloc] init];
        _label.font = [UIFont systemFontOfSize:80];
        _label.textColor = [UIColor whiteColor];
        _label.text = @"1";
        [_label sizeToFit];
        [self addSubview:_label];
    }
    return self;
}

- (void)layoutSubviews {
    [super layoutSubviews];
    CGSize mySize = self.bounds.size;
    _label.center = CGPointMake(mySize.width * 0.5f, mySize.height * 0.5f);
}

- (void)drawRect:(CGRect)rect {
    [self.color setFill];
    CGSize mySize = self.bounds.size;
    CGFloat radius = self.radius;
    [[UIBezierPath bezierPathWithOvalInRect:CGRectMake(mySize.width * 0.5f, mySize.height * 0.5f, self.radius, self.radius)] fill];
}
rob mayoff
  • 375,296
  • 67
  • 796
  • 848
  • Thank you for the code. is the reason why you don't want to allocate UIViews in drawrect because drawrect could be called multiple times? and in that way you would re-allocate the views each time? – Ramin Afshar Apr 08 '12 at 08:22
  • You shouldn't allocate a `UILabel` just to draw a string, and then throw away the `UILabel`. There are text-drawing APIs that are much less expensive if you just want to draw a string. It's ok to use a `UILabel` to draw a string if you are going to keep that `UILabel` around as part of your view hierarchy (like my example code does). If you are allocating views in your `drawRect:`, it's a sign that you are doing something inefficiently. – rob mayoff Apr 08 '12 at 20:51