什么是_UITemporaryLayoutWidth,它为什么打破我的约束?

问题描述:

我有一个Autolayout和Size Classes的故事板。相当复杂的布局,不幸的是,我不能真正确定如何在新项目中重现问题。
但是所讨论的视图被固定在屏幕的左和右边缘与具有750的优先级的约束(即|-([email protected])-[myView]-([email protected])-|,另外它具有大于或小于1000的优先级(即|-(>=0)-[myView]-(>=0)-|)约束等于。这是为了限制iPad的宽度,所以在容器约束中存在宽度约束width <= 600 @1000中心水平,并且视图的宽高比约束为3:1。说,很复杂什么是_UITemporaryLayoutWidth,它为什么打破我的约束?

Interface Builder不显示任何约束的问题。Xcode布局预览呈现正确的所有设备。

当我运行应用程序iOS告诉我它有冲突的约束。

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) 
(
    "<NSLayoutConstraint:0x7fd72853ff80 DMXKit.DipSwitchAssembly:0x7fd72990d0e0.width == 3*DMXKit.DipSwitchAssembly:0x7fd72990d0e0.height>", 
    "<NSLayoutConstraint:0x7fd728574e50 '_UITemporaryLayoutWidth' H:[DMXKit.DipSwitchAssembly:0x7fd72990d0e0(400)]>", 
    "<NSLayoutConstraint:0x7fd72856e9c0 V:[DMXKit.DipSwitchAssembly:0x7fd72990d0e0(133)]>" 
) 

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x7ffb19798000 DMXKit.DipSwitchAssembly:0x7ffb1979a000.width == 3*DMXKit.DipSwitchAssembly:0x7ffb1979a000.height> 

这重复了几次,具有完全相同的(即相同的指针)约束。这也很奇怪,看起来约束并没有被打破。运行时,该应用程序看起来100%正确。当我在Xcode视图调试器中查看应用程序时,地址为0x7ffb19798000的约束仍然存在,因此它从未被破坏。

_UITemporaryLayoutWidth constaint来自哪里?很明显,我没有添加它。谷歌不会吐出有关_UITemporaryLayoutWidth的任何有用信息。有没有人遇到过这样的问题?

+0

我有很多的这些警告也在日志中。虽然,它似乎没有打破我的布局。我想知道这些'_UITemporaryLayoutWidth来自哪里。 – dergab

问题的根源在于3:1的宽高比。如果我将其更改为其他方法,那么我现在使用4:1.4,它可以工作。我不知道为什么,但它有效。

我对自动布局的内部了解不多,但我认为问题在于布局引擎如何实现约束。大小类可能是添加临时宽度约束的原因。

不可满足的约束似乎不是一个真正的问题,因为它看起来像只是暂时不令人满意。这只是在每次创建视图时出现几行日志。

所以,我不确定这是否可以帮助你解决问题,因为它听起来像是在IB中构建你的布局,但是这里有一个问题,我刚才遇到的问题可能会帮助其他人搜索“_UITemporaryLayoutWidth ”。

我的方案是我在init中添加了自动布局约束,并在将视图添加到视图层次结构(修改按钮边缘插图触发器布局)之前意外触发了'layoutIfNeeded'。看起来系统添加了这些临时约束,并且(我假设?)在视图添加到层​​次结构后将其删除。如果你在你的布局中设置了特定的约束常量值(例如,你希望在这些按钮之间有16像素,但是在这个维度上有0个空间......),那么临时约束会设置0维(在我的情况下),这可能会失败。

更新:调查了一下,发现临时约束似乎与您用来初始化父视图的框架相对应。在我的情况下,我使用的框架是大小0x0,所以临时约束评估相对于0x0大小,从而失败。验证,如果我初始化一个5x5帧,然后我看到与_UITemporaryLayoutWidth(5)约束相同的错误。我注意到的另一件事是,约束似乎在布局评估过程中被添加和删除 - 如果在我触发布局和分析约束之前断开,我没有看到临时约束。我也没有看到错误后的约束,所以我怀疑他们综合了临时约束,添加它们,解决然后删除它们。

更新2:好吧,也许这是TMI,但这可能对某人有用。我目前的想法是,这些临时约束是对系统在单个视图层次结构中如何处理混合帧操作和自动布局的窥视。就我而言,我的观点没有父母,也没有限定其大小的限制,但它确实有一个零框架,这意味着系统假定它是解决布局时应该使用的大小。我的想法是,系统综合了这些视图的临时约束,这些视图的框架明确地设置为在系统遍历层次结构时解决系统的其余部分。

更新3:所以,我再次遇到这个问题,并希望分享一些信息。我的场景是,我试图基本测量没有使用systemLayoutSizeFittingSize:方法的父视图。长话短说,在测量之前,我必须在视图上调用layoutIfNeeded - 这是我遇到与临时约束冲突的地方,因为视图没有超视图。临时约束常量(维度)确实对应于在没有超视图的情况下在视图上设置的任何框架 - 我认为这是有意义的(尽管如此,在视图上设置一个框架,您将与AutoLayout一起使用看起来很奇怪。 )我能够解决临时约束问题 - 说如果视图没有超级视图然后将其添加到临时超级视图;测量;将其从临时超级视图中移除。希望这是有用的。

+12

...“在将视图添加到视图层次结构之前意外触发'layoutIfNeeded'” - 谢谢。 – Adama

+0

旅行者,你所寻求的答案在上面的评论中由Adama总结。 – Jano

+0

当一个视图还没有超级视图时,发生在我身上,但子视图使用AutoLayout会有一个复杂的布局。 – DevAndArtist

我我的情况下,问题是以下几点:

我创建了一个UIButton
我设置了它的宽度和高度约束。
我将按钮添加到其超级视图。
我将其领先和顶部布局约束设置为超视图。

这产生了错误“Unable to simultaneously satisfy constraints”,其中一个冲突约束是_UITemporaryLayoutHeight

当我将该按钮添加到它的超级视图之前,在之前设置其宽度和高度约束,错误消失了。

如上所述,临时约束似乎设置在没有父视图的视图上。我发现确保translatesAutoresizingMaskIntoConstraintsfalse在顶层视图中删除了临时约束。作为:

topView.translatesAutoresizingMaskIntoConstraints = false 

只是一个快速补充上述评论,简单的解决方案,我的工作是改变我的约束被创建的顺序。我以编程方式在视图和超级视图上创建约束 - 但我在超级视图之前完成视图。所以我交换了它,以便superview约束先行,然后子视图添加了它们的约束,这意味着不再需要调用_UITemporaryLayoutWidth,所以约束问题就消失了。

在我的情况,我只有在这种情况下,这个UITemporaryLayoutWidth冲突 1我与[UIView的新]一个观点,我并没有把它添加到任何上海华 2然后创建一个宽度约束这种观点只是创建 3调用layoutIfNeeded这种观点立即和冲突发生

所以要消除这种错误的方法很简单:不要叫layoutIfNeeded它自前加入一些上海华