Search code examples
objective-cios7autolayoutnslayoutconstraint

Centering view with visual format NSLayoutConstraints


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


Solution

  • 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