【问题标题】:updateViewConstraints called when creating constraints in viewDidLoad在 viewDidLoad 中创建约束时调用 updateViewConstraints
【发布时间】:2014-11-06 11:25:41
【问题描述】:

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

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

  • 如果我再次添加自动调整大小蒙版,应用程序可以正常工作,但我无法做我想做的事情(正确布局我的视图)。
  • 如果我在 updateViewConstraints 中创建约束,该应用程序也可以工作。

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

我想知道为什么会发生这种情况,以及将来我应该如何处理以使此类错误不再发生。我做错了吗?

编辑:

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

编辑 2:

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

那么当我被允许添加我的约束时?目前,我在将视图添加为子视图后立即添加它们。对于空消息,它在viewDidLoad 中,对于部分标题,它是viewForHeaderInSection。我必须使用setNeedsLayout之类的东西吗?

编辑 3:

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

【问题讨论】:

  • 我对这个问题感到困惑。在第一段中,您说您正在尝试删除自动调整大小的蒙版……如果您不想要蒙版,为什么要首先添加它?然后你说应用崩溃是因为你试图移除一个缺失的约束……你为什么要试图移除一个不存在的约束?
  • 感谢您的回复。默认情况下启用自动调整大小掩码。当我想使用自动布局时,我必须禁用它(translatesAutoresizingMaskIntoConstraints 设置为NO)。约束不存在,因为他没有在viewDidLoad 中完成创建它。当他想创建它时,他直接跳到updateViewConstraints 而不是创建我的约束...
  • 很抱歉,不,默认情况下不启用自动调整大小的蒙版。如果您以编程方式创建 UIView,它将没有设置自动调整大小的掩码,如果您在 xib/storyboard 文件中创建视图并在其中使用约束,则无法访问自动调整大小的掩码来打开它们。
  • 我正在以编程方式创建我的视图 :-) 感谢您的澄清。

标签: ios autolayout


【解决方案1】:

您不需要更改translatesAutoresizingMaskIntoConstraints 的值,除非您实际上已将autoresizingMask 设置为0 以外的值。如果您使用约束,解决方案是完全忽略autoresizingMasktranslatesAutoresizingMaskIntoConstraints

【讨论】:

  • 我没有为autoresizingMask 设置值。但是如果我没有将translatesAutoresizingMaskIntoConstraints 设置为NO,我会收到一个自动布局错误(无法同时满足约束)。在这里,我可以看到已应用了来自自动调整大小掩码的约束(在我的情况下,它表示标题的高度为 0)。比它制动我的一个约束并正确显示视图,但在控制台中显示自动布局错误。
【解决方案2】:

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

// 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;
}

到目前为止,我发现它与 headerviewempty message(视图)有关。当两者都使用时,我遇到了这个问题。要么应用程序崩溃,要么我得到 ​​p>

无法同时满足约束

取决于我是否关闭了自动调整大小的蒙版。有趣的是,我的解决方法只有 iOS 8 出现了这个问题。如果已设置约束,则解决方案是在viewDidLoad 中设置一个布尔变量,并在updateViewConstraints 中检查这一点。但我想知道造成这种情况的真正原因,而不是使用解决方法来解决问题......

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

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();

似乎解决了我的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-09
    • 2017-08-30
    • 2012-09-07
    相关资源
    最近更新 更多