Centering view with visual format NSLayoutConstraints

Joseph picture Joseph · Nov 16, 2013 · Viewed 17.6k times · Source

I am trying to center a view using the visual format language.

[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[_progressView(300)]-|" options:NSLayoutFormatAlignAllCenterY metrics:0 views:views]];

(views is a NSDictionaryOfVariableBindings containing _progressView)

It does not center my view (width: 300) within the self.view (width: 768). It aligns it left with an 8 pixel margin, as if I would have only written @"H:|-[_progressView(300)".

Is the only way to center the view using something like:?

[self.view addConstraint:[NSLayoutConstraint constraintWithItem:_progressView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual
                                                             toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1 constant:0]];

Thanks

Answer

DrummerB picture DrummerB · Nov 16, 2013

This format string

@"H:|-[_progressView(300)]-|"

doesn't tell AutoLayout to center progressView. Instead it says that progressView should be 300 wide and have a system defined standard margin on either side to the superview's edges. Obviously this can't be satisfied, so Auto Layout drops some of the constraints (you probably get some logs on the console). The constraint that is dropped in your case is probably the margin on the right.

To really center a view in it's superview you have to use the verbose constraint method instead of the visual string format, as you already figured out. However, you can easily put that into a nice category like this:

@interface UIView (MyLayout)
- (void)centerHorizontallyInSuperview;
@end

@implementation UIView (MyLayout)
- (void)centerHorizontallyInSuperview {
    NSLayoutConstraint *c;
    c = [NSLayoutConstraint constraintWithItem:self
                                     attribute:NSLayoutAttributeCenterX
                                     relatedBy:NSLayoutRelationEqual                                                             
                                        toItem:self.superview
                                     attribute:NSLayoutAttributeCenterX 
                                    multiplier:1 
                                      constant:0];
    [self.superview addConstraint:c];
}
@end