嵌入UIViewController的子容器的自动布局 [英] Auto layout of a Child Container that embeds a UIViewController

查看:85
本文介绍了嵌入UIViewController的子容器的自动布局的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的主要场景是通过将子容器放入其视图中并将子UIViewController嵌入该子容器中来显示子UIViewController.我可以通过ctrl从子容器拖到storyboard中的子UIViewController,然后选择嵌入" segue.

My main scene shows a child UIViewController, by putting a Child Container in its View, and embedding a child UIViewController in that Child Container. I do that by ctrl-dragging from the Child Container to the child UIViewController in the storyboard, and choosing the "embed" segue.

这使我可以封装子UIViewController并在其他地方重用.我认为这是相当标准的.但是我无法使其正确地自动布局.

That lets me encapsulate and reuse the child UIViewController elsewhere. I think that is fairly standard. But I can't get it to auto layout properly.

我已经做了一个简单的测试用例来证明这一点: https://github.com/murraycu/ios-example-自动布局子容器视图

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

它有两个UIViewControllers嵌入在Tab控制器中,因此您可以在它们之间进行切换.

It has two UIViewControllers that are embedded in a Tab Controller so you can switch between them.

简单"标签显示SimpleViewController,其中显示了图像和标签,在情节提要中可以看到:

The "Simple" tab shows the SimpleViewController, which shows an image and a label, seen here in the storyboard:

尽管UIImage或UILabel具有相等的宽度(等于父视图)约束以保持宽度简单,但都没有指定高度约束.

Neither the UIImage or the UILabel has a height constraint specified, though they have an Equal Width (equal to the parent view) constraint to keep the widths simple.

UILabel显然不是很高,但是UIImage和UILabel的Content Hugging优先级略有不同,因此根据自动版式",它们的高度不会模棱两可.因此,由于具有自动布局功能,当我在运行时将其文本设置为需要更多空间的某些文本时,它将占用更多空间,从而占用了其上方的UIImage的空间.很好-这是我想要的行为,如模拟器中所示:

That UILabel is clearly not very high but the UIImage and UILabel have slightly different Content Hugging priorities, making their heights not ambiguous according to Auto Layout. So thanks to auto layout, when I set its text at runtime to some text that would require more space, it takes up more space, taking space away from the UIImage above it. That's good - it is the behaviour that I want, as seen in the emulator:

现在出现问题:带有子容器"选项卡显示WithChildContainerViewController,它显示相同的图像,但显示我的ChildViewController(嵌入在子容器中)而不是UILabel.那个嵌入式的ChildViewController显示了UILabel.这是在情节提要中:

Now to the problem: The "With Child Container" tab shows the WithChildContainerViewController, which shows the same image but shows my ChildViewController (embedded in a Child Container) instead of the UILabel. And that embedded ChildViewController shows the UILabel. Here it is in the storyboard:

但是,自动布局系统现在似乎不知道子容器需要多少空间才能在ChildViewController中显示标签中的所有文本.与简单"选项卡中一样,UIImage或子容器均未指定高度限制.现在,XCode抱怨对于容器视图",高度不明确.在模拟器中看起来像这样:

However, the auto layout system now doesn't seem to know how much space the Child Container needs to show all the text in the label in my ChildViewController. As in the "Simple" tab, neither the UIImage or the Child Container has a height constraint specified. Now XCode complains that "Height is ambiguous for "container view". And it looks like this in the simulator:

如果我向子容器添加约束,将其底部约束到父视图的底部,则这种情况会得到改善,如@iphonic所建议:

That's improved if I add a constraint to the Child Container, constraining its 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 wrong:

如何让自动布局系统知道该怎么办?我曾考虑过实现UIView的internalContentSize,但UIViewController并非UIView.

How can I let the auto layout system know what to do? I've thought about implementing UIView's intrinsicContentSize, but UIViewController isn't a UIView.

推荐答案

建议是,以编程方式而不是通过IB进行.见下文

Suggestion is, do it programatically rather than via 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];

希望有帮助.

干杯.

这篇关于嵌入UIViewController的子容器的自动布局的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆