Center custom UIView vertically and horizontally using Auto Layout
Solution 1
Try adding a height and width constraint to your circle_view. I couldn't even get just a pain square view to appear at all without adding those (using your code, minus the layer stuff).
NSLayoutConstraint *heightConstraint =
[NSLayoutConstraint constraintWithItem:circle_view
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:100.0];
[circle_view addConstraint:heightConstraint];
NSLayoutConstraint *widthConstraint =
[NSLayoutConstraint constraintWithItem:circle_view
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:100.0];
[circle_view addConstraint:widthConstraint];
Solution 2
Just to add to rdelmar's answer:
The core issue is that as soon as you go the NSLayoutConstraint
route, and specify setTranslatesAutoresizingMaskIntoConstraints:NO
, the frame you made with CGRectMake
is rendered irrelevant for AutoLayout purposes. That's why it didn't use the info from the frame's height and width.
phor2
Updated on July 29, 2020Comments
-
phor2 almost 4 years
I'm trying to build a rather simple animated custom UI using the Auto Layout API newly available iOS 6. The custom view I'm building has a circle that I want to be both vertically and horizontally centered.
Unfortunately I can't figure out why my constraints appear to work fine for UIButton, and UILabel elements but yield weird results when I use a custom view with and custom CALayer (in this case a circle, that will eventually be animated).
To be clear I don't want my view to expand to fill the whole screen, but rather to have dynamic "padding" so that the view is vertically centered both on the iPhone 4 and 5. I should also note that I'm very new to Cocoa and UIKit.
RootViewController.m:
... - (void)viewDidLoad { [super viewDidLoad]; // Create Circle View CGRect circle_view_rect = CGRectMake(0, 0, 100, 100); UIView *circle_view = [[UIView alloc] initWithFrame:circle_view_rect]; // Create Circle Layer CircleLayer *circle_layer = [[CircleLayer alloc] init]; circle_layer.needsDisplayOnBoundsChange = YES; circle_layer.frame = circle_view.bounds; [circle_view.layer addSublayer:circle_layer]; // Enable Auto Layout [circle_view setTranslatesAutoresizingMaskIntoConstraints:NO]; [self.view addSubview:circle_view]; // Center Vertically NSLayoutConstraint *centerYConstraint = [NSLayoutConstraint constraintWithItem:circle_view attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0.0]; [self.view addConstraint:centerYConstraint]; // Center Horizontally NSLayoutConstraint *centerXConstraint = [NSLayoutConstraint constraintWithItem:circle_view attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0.0]; [self.view addConstraint:centerXConstraint]; } ...
CircleLayer.m:
... - (void)drawInContext:(CGContextRef)context { CGContextAddArc(context, 50, 50, 50, 0.0, 2*M_PI, 0); CGContextSetFillColorWithColor(context, [UIColor yellowColor].CGColor); CGContextFillPath(context); } ...
Basically the constraints I've implemented are:
- center vertically inside parent view
- center horizontally inside parent view
And this is the result I get:
Any help would be greatly appreciated, I've been pondering this one for a few days now.
Thanks
-
phor2 over 11 yearsThanks! That does exactly what I want. No more ambiguous layout warnings. :)
-
Mihail Velikov almost 9 yearsIt took me a while until I understand that this code is an addition to the code from the question above. Thanks guys!
-
Eddie Deng over 8 yearsthis answer solved my problem. Even a frame is specified using initWithFrame: constructor, it is immediately invalidated upon calling etTranslatesAutoresizingMaskIntoConstraints:NO