【发布时间】:2015-10-16 21:10:46
【问题描述】:
我正在尝试为每个方向切换我的项目的自动布局约束,并通过以编程方式删除和添加NSAutoLayoutConstraints 的纵向和横向集来实现此目的。我对两个方向的布局都有正确的自动布局约束(我认为)。我的情节提要不使用大小类来实现兼容性。
我已经截取了正确布局的屏幕截图。红色部分是红色的 UIView。
我的 viewWillLayoutSubviews: 是
- (void)viewWillLayoutSubviews {
[self.termToolbar invalidateIntrinsicContentSize];
}
所有添加和删除的约束都在updateViewConstraints
在纵向启动应用程序然后旋转到横向时,出现约束错误:
2015-07-26 10:50:42.856 reproduce[1084:23311] 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)
(
"<_UILayoutSupportConstraint:0x786436c0 V:[_UILayoutGuide:0x7864cb70(20)]>",
"<_UILayoutSupportConstraint:0x78643680 V:|-(0)-[_UILayoutGuide:0x7864cb70] (Names: '|':UIView:0x7864ca90 )>",
"<NSLayoutConstraint:0x78657bc0 'UIView-Encapsulated-Layout-Width' H:[UIView:0x7864ca90(480)]>",
"<NSLayoutConstraint:0x78657bf0 'UIView-Encapsulated-Layout-Height' V:[UIView:0x7864ca90(320)]>",
"<NSLayoutConstraint:0x786593c0 V:[_UILayoutGuide:0x7864cb70]-(0)-[UISearchBar:0x78a21a70]>",
"<NSLayoutConstraint:0x786593f0 V:[UISearchBar:0x78a21a70]-(0)-[UITableView:0x7982aa00]>",
"<NSLayoutConstraint:0x78659420 V:[UITableView:0x7982aa00]-(0)-[UIView:0x78a216f0]>",
"<NSLayoutConstraint:0x78620570 V:[UIView:0x78a216f0]-(0)-[UIToolbar:0x78b81d00]>",
"<NSLayoutConstraint:0x786205a0 V:[UIToolbar:0x78b81d00]-(0)-| (Names: '|':UIView:0x7864ca90 )>",
"<NSLayoutConstraint:0x786590a0 UIView:0x78a216f0.height == 0.75*UIView:0x78a216f0.width>",
"<NSLayoutConstraint:0x786596d0 H:|-(0)-[UIView:0x78a216f0] (Names: '|':UIView:0x7864ca90 )>",
"<NSLayoutConstraint:0x78659720 H:[UIView:0x78a216f0]-(0)-| (Names: '|':UIView:0x7864ca90 )>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x786593f0 V:[UISearchBar:0x78a21a70]-(0)-[UITableView:0x7982aa00]>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
请注意,我正在从纵向旋转到横向,并且显示的错误是针对纵向方向!从横向旋转到纵向时,不会出现调试输出/错误。旋转回横向会导致相同的错误。
即使出现这些错误,在我显示 UIAlertView/Controller 之前,视图布局对于纵向和横向都很好。一旦显示警报,布局就会失败,并且 纵向和横向布局都显示错误(UITableView 消失,红色 UIView 占据整个屏幕等)。 警报被解除或仍然显示无关紧要,每次警报后布局都会失败。
我创建了一个示例项目来重现此行为,可以在 here 找到。 UI 元素插座在 IB 中连接。所有代码都在默认的 ViewController 类中。知道为什么会发生这种行为,或者这是 AutoLayout 中的一个错误,用于在方向之间进行简单的布局更改?谢谢。
纵向限制:
<NSLayoutConstraint:0x7b05cda0 V:|-(0)-[_UILayoutGuide:0x7b0648a0] (Names: '|':UIView:0x7b064990 )>,
<NSLayoutConstraint:0x7b05cc30 V:[_UILayoutGuide:0x7b0648a0]-(0)-[UISearchBar:0x7b0e9590]>,
<NSLayoutConstraint:0x7b05cc00 V:[UISearchBar:0x7b0e9590]-(0)-[UITableView:0x7cb4d600]>,
<NSLayoutConstraint:0x7b05cbd0 V:[UITableView:0x7cb4d600]-(0)-[UIView:0x7b0e9210]>,
<NSLayoutConstraint:0x7b05cba0 V:[UIView:0x7b0e9210]-(0)-[UIToolbar:0x7b069f10]>,
<NSLayoutConstraint:0x7b05cb70 V:[UIToolbar:0x7b069f10]-(0)-| (Names: '|':UIView:0x7b064990 )>,
<NSLayoutConstraint:0x7b05ced0 UIView:0x7b0e9210.height == 0.75*UIView:0x7b0e9210.width>,
<NSLayoutConstraint:0x7b05c990 H:|-(0)-[UISearchBar:0x7b0e9590] (Names: '|':UIView:0x7b064990 )>,
<NSLayoutConstraint:0x7b05c940 H:[UISearchBar:0x7b0e9590]-(0)-| (Names: '|':UIView:0x7b064990 )>,
<NSLayoutConstraint:0x7b05c8a0 H:|-(0)-[UIView:0x7b0e9210] (Names: '|':UIView:0x7b064990 )>,
<NSLayoutConstraint:0x7b05c850 H:[UIView:0x7b0e9210]-(0)-| (Names: '|':UIView:0x7b064990 )>,
<NSLayoutConstraint:0x7b05c780 H:|-(0)-[UITableView:0x7cb4d600] (Names: '|':UIView:0x7b064990 )>,
<NSLayoutConstraint:0x7b05c730 H:[UITableView:0x7cb4d600]-(0)-| (Names: '|':UIView:0x7b064990 )>,
<NSLayoutConstraint:0x7b05c6c0 H:|-(0)-[UIToolbar:0x7b069f10] (Names: '|':UIView:0x7b064990 )>,
<NSLayoutConstraint:0x7b05c670 H:[UIToolbar:0x7b069f10]-(0)-| (Names: '|':UIView:0x7b064990 )>
景观限制:
<NSLayoutConstraint:0x7b05c530 V:|-(0)-[_UILayoutGuide:0x7b0648a0] (Names: '|':UIView:0x7b064990 )>,
<NSLayoutConstraint:0x7b05c4e0 V:[_UILayoutGuide:0x7b0648a0]-(0)-[UISearchBar:0x7b0e9590]>,
<NSLayoutConstraint:0x7b05c4b0 V:[UISearchBar:0x7b0e9590]-(0)-[UIView:0x7b0e9210]>,
<NSLayoutConstraint:0x7b05c480 V:[UIView:0x7b0e9210]-(0)-[UIToolbar:0x7b069f10]>,
<NSLayoutConstraint:0x7b05c450 V:[UIToolbar:0x7b069f10]-(0)-| (Names: '|':UIView:0x7b064990 )>,
<NSLayoutConstraint:0x7b05c290 V:|-(0)-[_UILayoutGuide:0x7b0648a0] (Names: '|':UIView:0x7b064990 )>,
<NSLayoutConstraint:0x7b05c240 V:[_UILayoutGuide:0x7b0648a0]-(0)-[UISearchBar:0x7b0e9590]>,
<NSLayoutConstraint:0x7b05c210 V:[UISearchBar:0x7b0e9590]-(0)-[UITableView:0x7cb4d600]>,
<NSLayoutConstraint:0x7b05c1e0 V:[UITableView:0x7cb4d600]-(0)-[UIToolbar:0x7b069f10]>,
<NSLayoutConstraint:0x7b05c1b0 V:[UIToolbar:0x7b069f10]-(0)-| (Names: '|':UIView:0x7b064990 )>,
<NSLayoutConstraint:0x7b05bf70 H:|-(0)-[UITableView:0x7cb4d600] (Names: '|':UIView:0x7b064990 )>,
<NSLayoutConstraint:0x7b05bf20 H:[UITableView:0x7cb4d600]-(0)-[UIView:0x7b0e9210]>,
<NSLayoutConstraint:0x7b05bef0 H:[UIView:0x7b0e9210]-(0)-| (Names: '|':UIView:0x7b064990 )>,
<NSLayoutConstraint:0x7b05c2f0 UIView:0x7b0e9210.height == 0.75*UIView:0x7b0e9210.width>,
<NSLayoutConstraint:0x7b05be30 H:|-(0)-[UISearchBar:0x7b0e9590] (Names: '|':UIView:0x7b064990 )>,
<NSLayoutConstraint:0x7b05bde0 H:[UISearchBar:0x7b0e9590]-(0)-| (Names: '|':UIView:0x7b064990 )>,
<NSLayoutConstraint:0x7b05bd70 H:|-(0)-[UIToolbar:0x7b069f10] (Names: '|':UIView:0x7b064990 )>,
<NSLayoutConstraint:0x7b05bd20 H:[UIToolbar:0x7b069f10]-(0)-| (Names: '|':UIView:0x7b064990 )>
【问题讨论】:
-
"我有正确的自动布局约束" 不,你没有!如果你这样做了,你就不会出错。错误很明显。你已经过度确定了你的约束。你有垂直约束,你有水平约束,然后你有一个规则,一个特定视图的高度总是正好是其宽度的 3/4。你不可能拥有所有这些;如果您要像这样一直向下固定所有内容,则该视图需要更改其纵横比的空间。
-
4:3 的纵横比适用于红色的 UIView。不过,我仍然没有看到我的约束之间的冲突。表格视图不应该增长/缩小以适应两个方向的红色 UIView 吗? (另外,为什么调试器抱怨我要删除的约束???)
-
@matt 好的,所以我的约束是错误的并导致错误。你能举一个例子说明我的约束是如何不适合的吗?我在考虑我的理想布局时做出了约束,我看不出这些约束如何在 iPhone 屏幕尺寸上发生冲突,所以也许我的心理形象并没有考虑到布局中所有可能的冲突。我在问题中添加了我的程序化纵向和横向约束列表。谢谢。
-
所以在我交换约束的
updateViewConstraints之前抛出了约束调试错误......我认为这就是问题所在。我应该在哪里设置我的新约束?我是根据这个 SO 帖子进行的:stackoverflow.com/questions/17772922/… 但显然将更新代码放入updateViewConstraints是不正确的。现在我可以在第一次设置约束后通过在viewWillLayoutSubviews中调用setNeedsUpdateConstraints来修补这个问题,但不是太理想...... :( -
“你能举个例子说明我的约束是如何不适合的吗?”我不必——这就是布局引擎正在做的事情!
标签: ios autolayout uialertview nslayoutconstraint uialertcontroller