I just started learning AutoLayout for iOS and had a look at Visual Format Language.
It all works fine except for one thing: I just can\'t get a view to center withi
Yes, it is possible to center a view in its superview with Visual Format Language. Both vertically and horizontally. Here is the demo:
https://github.com/evgenyneu/center-vfl
Add below code and have your button at the center of the screen. Absolutely possible.
[self.view addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"H:|-[button]-|"
options:NSLayoutFormatAlignAllCenterY
metrics:0
views:views]];
[self.view addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"V:|-[button]-|"
options:NSLayoutFormatAlignAllCenterX
metrics:0
views:views]];
For those who came here for an Interface Builder
based solution (Google leads me here), just add const width/height constraints, and select the subview -> control drag to it's superview -> select "center vertically/horizontally in superview".
You can use extra views.
NSDictionary *formats =
@{
@"H:|[centerXView]|": @0,
@"V:|[centerYView]|": @0,
@"H:[centerYView(0)]-(>=0)-[yourView]": @(NSLayoutFormatAlignAllCenterY),
@"V:[centerXView(0)]-(>=0)-[yourView]": @(NSLayoutFormatAlignAllCenterX),
};
NSDictionary *views = @{
@"centerXView": centerXView,
@"centerYView": centerYView,
@"yourView": yourView,
};
^(NSString *format, NSNumber *options, BOOL *stop) {
[superview addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:format
options:options.integerValue
metrics:nil
views:views]];
}];
If you want it neat, then centerXView.hidden = centerYView.hidden = YES;
.
PS: I am not sure I can call the extra views "placeholders", because English is my second language. It will be appreciated if someone can tell me that.
Instead of using VFL, you can easily do this in interface builder. In the Main Storyboard, ctrl+click on the view you want to center. Drag to the superview (while holding ctrl) and select "Center X" or "Center Y". No code needed.
I think it is better to manually create constraints.
[superview addConstraint:
[NSLayoutConstraint constraintWithItem:view
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:superview
attribute:NSLayoutAttributeCenterX
multiplier:1
constant:0]];
[superview addConstraint:
[NSLayoutConstraint constraintWithItem:view
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:superview
attribute:NSLayoutAttributeCenterY
multiplier:1
constant:0]];
Now we can use NSLayoutAnchor to programatically define AutoLayout:
(Available in iOS 9.0 and later)
view.centerXAnchor.constraint(equalTo: superview.centerXAnchor).isActive = true
view.centerYAnchor.constraint(equalTo: superview.centerYAnchor).isActive = true
I recommend using SnapKit, which is a DSL to make Auto Layout easy on both iOS and macOS.
view.snp.makeConstraints({ $0.center.equalToSuperview() })