以编程方式添加控制器视图时自定义自动布局约束被破坏

Posted

技术标签:

【中文标题】以编程方式添加控制器视图时自定义自动布局约束被破坏【英文标题】:Custom autolayout constraints broken when adding a controller's view programmatically 【发布时间】:2014-06-24 16:30:53 【问题描述】:

我有一个 myController,我以这种方式插入代码中(在 self = 根视图控制器中):

    MyViewController* myController = [[MyViewController alloc] initWithNibName:nil bundle:nil];
    [self addChildViewController:myController];
    [self.view addSubview:myController.view];
    myController.view.frame = CGRectMake(0, 504, 320, 216);

在 MyViewController 的 xib 文件中,我只有 2 个视图,一个在另一个之上。假设顶视图称为 View1,底视图称为 View2。 View0 为主视图。

我添加了以下垂直 NSLayoutConstraints : 五:[查看2(40)] V:|-(0)-View1 (名称:'|':View0 ) V:View2-(0)-| (名称:'|':View0 ) V:View1-(0)-View2

也就是说View1在顶部接触View0,而View2在底部。并且View2在顶部接触View1,在底部接触View0,并且高度恒定为40。

当我以纵向运行时,一切似乎都很好。但是当我旋转到横向时,有时会出现以下错误。

Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
"<NSAutoresizingMaskLayoutConstraint:0xd17cc00 h=--& v=--& V:[UIView:0xd174a30(268)]>",
"<NSLayoutConstraint:0x9469890 V:[View2(40)]>",
"<NSLayoutConstraint:0x9468e90 V:|-(0)-View1   (Names: '|':View0 )>",
"<NSLayoutConstraint:0x9468ef0 V:View2-(0)-|   (Names: '|':View0 )>",
"<NSLayoutConstraint:0x94676f0 V:View1-(0)-View2>",
"<NSAutoresizingMaskLayoutConstraint:0x9450640 h=-&- v=-&- UIView:0000.height == UIView:0xd174a30.height - 268>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x9469890 V:[View2(40)]>

Break on objc_exception_throw to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.

有人明白我为什么会这样吗?我应该怎么做才能使我定义的约束保持在先?

【问题讨论】:

【参考方案1】:

好吧,最后,为了解决这个问题,我不得不在 View0 上将 translatesAutoresizingMaskIntoConstraints 设置为 NO。

然后,为了很好地显示我的 View0,我必须为 View0 手动创建 NSLayoutConstraint 并将这些约束添加到 View0 的超级视图中。

【讨论】:

【参考方案2】:

自动调整掩码是在 ios 中进行布局的传统方式(在 iOS 6 中自动布局之前)。 UIView 上有一个属性可以自动将此遗留系统转换为布局约束,称为 translatesAutoresizingMaskIntoConstraints,默认为 YES。如果您在代码中(或在某些情况下使用 IB)创建视图并打算使用自动布局来定位它,则应将此属性设置为 NO 以避免出现上述问题。每当您在约束警告中看到那些 NSAutoresizingMaskLayoutConstraint 约束类型时,这可能就是原因。

【讨论】:

以上是关于以编程方式添加控制器视图时自定义自动布局约束被破坏的主要内容,如果未能解决你的问题,请参考以下文章

如何以编程方式使用自动布局添加自定义视图

以编程方式将自动布局约束添加到恒定宽度和高度的子视图

自动布局约束没有得到尊重

自动布局 - 以编程方式定义异常约束

iOS 以编程方式生成的视图具有隐藏的约束,导致与自动布局发生冲突

程序化自动布局更改 UIView 的行为