Automatic layout of a child container embedding a UIViewController

In my main scene, the child element of the UIViewController , placing the child container in its view and embedding the child UIViewController in this child container. I do this by ctrl-dragging from the child container to the child UIViewController in the storyboard and selecting the "embed" segue.

This allows me to encapsulate and reuse a child of a UIViewController elsewhere. I think this is pretty standard. But I can’t configure it correctly.

I did a simple test case to demonstrate this: https://github.com/murraycu/ios-example-autolayout-of-child-container-views

It has two UIViewControllers built into the tab controller, so you can switch between them.

On the Simple tab, SimpleViewController displayed, where the image and label that are visible here in the storyboard are displayed:

SimpleViewController

Neither UIImage nor UILabel have a height limit, although they have an Equal Width limit (equal to the parent view) to simplify the width.

That UILabel is clearly not very large, but UIImage and UILabel have slightly different Content Hugging priorities, making their heights not ambiguous according to Auto Layout. Thus, thanks to the automatic layout, when I set my text while some text is required that requires more space, it takes up more space, taking the space from the UIImage above it. This is good - this is the behavior I want, as seen from the emulator:

SimpleViewController in the emulator

Now, before the problem: the tab “With a child container” displays WithChildContainerViewController, which shows the same image, but shows my ChildViewController (built into the container for children) instead of UILabel. And this built-in ChildViewController shows UILabel. Here it is in the storyboard:

WithChildContainerViewController

However, the automatic layout system now does not seem to know how much space in the child container should display all the text in the shortcut of my ChildViewController. Like the Simple tab, neither the UIImage nor the Child Container has a height limit. Now Xcode complains that “Height is ambiguous for the“ container view. ”And it looks like a simulator:

WithChildContainerViewController in the emulator

This improved if I add a constraint to the child container, restricting it from the bottom to the bottom of the parent view, as suggested by @iphonic: https://github.com/murraycu/ios-example-autolayout-of-child-container-views / commit / 1d295fe0a6c4502764f8725d3b99adf8dab6b9ae , but the height is still incorrect:

enter image description here

How can I let the automatic layout system know what to do? I was thinking of implementing a UIView intrinsicContentSize, but the UIViewController is not a UIView.

+5
source share
2 answers

The suggestion is to do this programmatically, and not through IB. See below

  _childController=[self.storyboard instantiateViewControllerWithIdentifier:@"ChildController"]; [self addChildViewController:_childController]; [_container addSubview:_childController.view]; [_childController didMoveToParentViewController:self]; _childController.view.frame=_container.bounds; //add constraints UIView *subView=_childController.view; UIView *parent=_container; subView.translatesAutoresizingMaskIntoConstraints=NO; NSLayoutConstraint *width =[NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeWidth relatedBy:0 toItem:parent attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0]; NSLayoutConstraint *height =[NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeHeight relatedBy:0 toItem:parent attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0]; NSLayoutConstraint *top = [NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:parent attribute:NSLayoutAttributeTop multiplier:1.0f constant:0.f]; NSLayoutConstraint *leading = [NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:parent attribute:NSLayoutAttributeLeading multiplier:1.0f constant:0.f]; [parent addConstraint:width]; [parent addConstraint:height]; [parent addConstraint:top]; [parent addConstraint:leading]; 

Hope this helps.

Greetings.

+2
source

@iphonic, but using the language Visual Format

 _childController = [self.storyboard instantiateViewControllerWithIdentifier: @"ChildController"]; [self addChildViewController: _childController]; [_container addSubview: _childController.view]; [_childController didMoveToParentViewController: self]; //add constraints NSDictionary *views = @{@"subView": _childController.view, @"parent": _container}; [parent addConstraints:[NSLayoutConstraint constraintsWithVisualFormat: @"V:|[subView(==parent)]" options: 0 metrics: nil views: views]]; [parent addConstraints: [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[subView(==parent)]" options: 0 metrics: nil views: views]]; 
0
source

Source: https://habr.com/ru/post/989382/


All Articles