使用UIAlertView / Controller的Autolayout错误?

我正在尝试为每个方向切换项目的Autolayout约束,并通过编程方式删除和添加NSAutoLayoutConstraints的纵向和横向集合。 我对两种方向的布局都有正确的自动布局约束(我认为)。 我的故事板没有使用Size Classes来兼容。

我截取了正确布局的截图。 红色部分是一个红色的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占用整个屏幕,等等)。 无论警报是否已被解除或仍然存在 ,布局将在警报后每次都失败。

我创建了一个示例项目来重现此处可以找到的行为。 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 )>

我还为此提交了一份Apple Bug Report和TSI,并得到了很好的答复。

在设备返回的方向更改之前调用的方法的解决方案取决于您想要支持的iOS版本。

iOS <8 willRotateToInterfaceOrientation:

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];

    [self.view setNeedsUpdateConstraints];
}

iOS 8 + viewWillTransitionToSize:以及一些检查来确定我们所处的方向。

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
    if (size.width < size.height && self.view.bounds.size.width > self.view.bounds.size.height) {
        [NSLayoutConstraint deactivateConstraints:landscapeConstraints];
    } else if (size.width > size.height && self.view.bounds.size.width < self.view.bounds.size.height) {
        [NSLayoutConstraint deactivateConstraints:portraitConstraints];
    }
    [self.view setNeedsUpdateConstraints];
}
链接地址: http://www.djcxy.com/p/91595.html

上一篇: Autolayout bug with UIAlertView/Controller?

下一篇: Layout properly in this case?