Reputation: 248
Within my root view controller, I'm adding a child view controller's view as a subview, as follows:
ChildViewController *cvc = [[ChildViewController alloc] init];
[self addChildViewController:cvc];
[self.view addSubview:cvc.view];
[cvc didMoveToParentViewController:self];
and I'd now like to use a NSLayoutConstraint to position the cvc.view within the parent view (self.view), such that cvc.view is positioning 25 pts above the bottom of the parent view. My understanding is that the following should work:
UIView *superview = self.view;
UIView *childview = cvc.view;
NSLayoutConstraint *cn =
[NSLayoutConstraint withItem:childview
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:superview attribute:NSLayoutAttributeBottom
multiplier: 1.0
constant: -25.0];
[superview addConstraint: cn];
But the constraint fails at runtime. I thought initially maybe the autoresizing mask in the child view was causing problems (and following the WWDC 2012 Intro video on auto layout), so I set [childview setTranslatesAutoresizingMaskIntoConstraints:NO]
, but then the childview simply fails to appear.
What am I doing wrong?
Upvotes: 7
Views: 7404
Reputation: 204
To properly setup and size your child view controller with auto layout do the following:
childView.translatesAutoresizingMaskIntoConstraints = NO;
NSLayoutConstraint *left = [NSLayoutConstraint constraintWithItem:superview attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:childview attribute:NSLayoutAttributeLeft multiplier:1 constant:0];
[self.view addConstraint:left];
NSLayoutConstraint *top = [NSLayoutConstraint constraintWithItem:superview attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:childview attribute:NSLayoutAttributeTop multiplier:1 constant:0];
[self.view addConstraint:top];
NSLayoutConstraint *width = [NSLayoutConstraint constraintWithItem:superview attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:childview attribute:NSLayoutAttributeWidth multiplier:1 constant:0];
[self.view addConstraint:width];
NSLayoutConstraint *height = [NSLayoutConstraint constraintWithItem:superview attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:childview attribute:NSLayoutAttributeHeight multiplier:1 constant:0];
[self.view addConstraint:height];
If you prefer the visual format you can do the following:
childView.translatesAutoresizingMaskIntoConstraints = NO;
NSDictionary *views = @{@"childview": childview};
[superview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-0-[childview]-0-|" options:0 metrics:nil views:views]];
[superview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[childview]-0-|" options:0 metrics:nil views:views]];
Upvotes: 0
Reputation: 2417
I'm not sure but the following should work, or something very similar:
UIView *superview = self.view;
UIView *childview = cvc.view;
NSDictionary *constrainedViews = NSDictionaryOfVariableBindings(childview);
NSArray *constraints =
[superview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[childview]-25-|"
options:0
metrics:nil
views:constrainedViews];
If not make sure that you are actually setting a size for the childview, something like:
UIView *superview = self.view;
UIView *childview = cvc.view;
NSDictionary *constrainedViews = NSDictionaryOfVariableBindings(childview);
NSArray *constraints =
[superview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[childview]|"
options:0
metrics:nil
views:constrainedViews];
Say, to make it fill the width of the view. Or:
UIView *superview = self.view;
UIView *childview = cvc.view;
NSDictionary *constrainedViews = NSDictionaryOfVariableBindings(childview);
NSArray *constraints =
[superview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[childview(>100,<304)]-|"
options:0
metrics:nil
views:constrainedViews];
Which means something like childview should have a width bigger than 100 but less than 304 with default margins to the superview. Please note I don't know if the above constraint actually makes sense (e.g. it may just always give you 304 width childview as that would leave default margins), but it serves as an example.
Upvotes: 3