Reputation: 30479
Apple's documentation on creating Auto Layout constraints between a view and one of the layout guides only shows an example using VFL.
Is there any way to create these constraints programmatically without VFL (using NSLayoutConstraint
's other API or similar)?
(Note: I'm specifically asking about doing this in code, not in Interface Builder. And I don't want the calculated length
of the guide set as a static constant on a constraint, I want a constraint where changes to the layout guide length would automatically cause the constrained view to adjust position.)
Upvotes: 65
Views: 28258
Reputation: 61
Just an addition to @Jamie McDaniel, in case it's not immediately obvious, you need to add the constraint that he suggests to create:
NSLayoutConstraint *buttonTopConstraint = [NSLayoutConstraint constraintWithItem:self.button
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self.topLayoutGuide
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:20.0];
[self.view addConstraint:buttonTopConstraint];
Upvotes: 3
Reputation: 4726
To supplement @JamieMcDaniel's answer, the Swift + iOS9 version would be:
self.button.topAnchor
.constraintEqualToAnchor( self.topLayoutGuide.bottomAnchor ).active = true
Don't forget the .active = true
part as otherwise the constraint doesn't kick in automatically.
Upvotes: 6
Reputation: 1808
For a UIButton
that you want to place 20 points below the UIViewController.topLayoutGuide
you create the NSLayoutConstraint
like so:
[NSLayoutConstraint constraintWithItem:self.button
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self.topLayoutGuide
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:20.0];
With iOS 9 you can also create the NSLayoutConstraint
this way:
[self.button.topAnchor constraintEqualToAnchor:self.topLayoutGuide.bottomAnchor
constant:20.0];
Upvotes: 93
Reputation: 26383
This is a gist I've created, you are supposed to embed all your subviews into a tank view(container view) added into a xib, it removes tank view-superview xib constraints and adds an upper constraints to topLayoutGuide giving an iOS6 look. It could be interesting for what you want to achieve.
//This should be added before the layout of the view
- (void) adaptToTopLayoutGuide {
//Check if we can get the top layoutguide
if (![self respondsToSelector:@selector(topLayoutGuide)]) {
return;
}
//tankView is a contaner view
NSArray * array = [self.tankView referencingConstraintsInSuperviews]; //<--For this method get the Autolayout Demistified Book Sample made by Erica Sadun
[self.view removeConstraints:array];
NSArray * constraintsVertical = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[topLayoutGuide]-0-[tankView]|" options:0 metrics:nil views:@{@"tankView": self.tankView, @"topLayoutGuide":self.topLayoutGuide}];
[self.view addConstraints:constraintsVertical];
NSArray * constraintsHorizontal = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[tankView]|" options:0 metrics:nil views:@{@"tankView": self.tankView}];
[self.view addConstraints:constraintsHorizontal];
}
Upvotes: 3