在viewDidLoad中创建约束时调用updateViewConstraints

时间:2014-11-06 11:25:41

标签: ios autolayout

目前我遇到了一种奇怪的行为。我从viewForHeaderInSection的视图中删除了自动调整大小的蒙版。当我这样做时,应用程序崩溃,因为我试图删除一个nil的约束。

我在父控制器的viewDidLoad中创建了相关的约束。在调试模式下,我发现当系统尝试创建一个约束,其中涉及我的子视图控制器(它具有从部分标题视图中删除的自动调整大小掩码),它直接跳转到updateViewConstraints。当然,约束是零,因为尚未创建。

  • 如果我再次添加自动调整大小屏幕应用程序有效,但我无法做我想做的事情(正确布局我的观点)。
  • 如果我在updateViewConstraints中创建约束,则该应用也可以。

我不明白为什么会这样。在类似的视图控制器上,它可以正常工作。有时我认为自动布局更多的是痛苦而非收益。在服务器错误上显示警报。这里可以正确加载视图。似乎这是一种计时问题。

我想知道为什么会发生这种情况,以后我该怎么办这样的错误不会再发生了。我做错了吗?

修改

不知道它是否有帮助,但是如果我在我父母的setNeedsLayout中对我的子视图控制器的视图调用layoutIfNeededviewDidLoad,那么应用程序也会崩溃。

编辑2:

当我在视图控制器的不同位置添加带有约束的多个视图时,似乎会发生这种情况。对于我的表,如果当前没有条目,我会添加一条空消息。如果我没有将标签作为子视图添加到我的表中,一切正常。

所以,当我允许添加约束时?目前我在视图添加为子视图后立即添加它们。对于空消息,它位于viewDidLoad,而节标题为viewForHeaderInSection。我是否必须使用类似setNeedsLayout的内容?

编辑3:

在表格视图中添加子视图根本不是一个好主意(特别是在使用自动布局时)。目前我正在使用背景视图,但这不是我正在寻找的解决方案。

2 个答案:

答案 0 :(得分:0)

除非您实际将translatesAutoresizingMaskIntoConstraints设置为0以外的其他值,否则无需更改autoresizingMask的值。如果您使用约束,则解决方案是完全忽略{{1} }和autoresizingMask

答案 1 :(得分:0)

现在我又遇到了同样的问题。我的解决方法没有奏效:

// on iOS 7 this would bring "Auto Layout still required after executing -layoutSubviews. UITableView's implementation of -layoutSubviews needs to call super." and the app crashes
// on iOS 8 this is needed, otherwise "Unable to simultaneously satisfy constraints."
// bug?
if (UIDevice.CurrentDevice.CheckSystemVersion (8, 0)) {
    sectionHeader.TranslatesAutoresizingMaskIntoConstraints = false;
}

到目前为止,我发现它与标题视图空信息(视图)有关。当两者都使用时,我遇到了这个问题。应用程序崩溃或我得到

  

无法同时满足约束

取决于我是否关闭了自动调整遮罩。有趣的是,只有iOS 8通过我的解决方法解决了这个问题。如果已经设置了约束并且在viewDidLoad中检查了这个约束,则解决方案是在updateViewConstraints中设置布尔变量。但我想知道这个的真正原因,而不是使用解决方法来解决这个问题......

每次检索我的表的新数据时,我都会检查记录数是否为零。如果它们为零,我就会显示空信息。问题似乎是由reloadData引起的,我在此检查之前调用了它。 UITableViewHeaderFooterContentView的{​​{1}}高度为NSAutoresizingMaskLayoutConstraint。将我的代码重构为此变体

if (myList.Count == 0) {
    this.TableView.BackgroundView = emptyMessage;
    this.TableView.SeparatorStyle = UITableViewCellSeparatorStyle.None;
} else {
    this.TableView.BackgroundView = null;

    this.TableView.SeparatorStyle = UITableViewCellSeparatorStyle.SingleLine;
    if (emptyMessage != null) {
        emptyMessage.RemoveFromSuperview ();
    }
}
// call this afterwards!
TableView.ReloadData();

似乎解决了我的问题。