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

Mat*_*uch 43 ios autolayout nslayoutconstraint

我有一个包含Autolayout和Size Classes的故事板.相当复杂的布局,不幸的是我无法确定如何在新项目中重现问题.
但是有问题的视图被固定到屏幕的左边缘和右边缘,其约束具有750优先级(即|-(0@750)-[myView]-(0@750)-|,另外它具有大于或等于约束的优先级为1000(即|-(>=0)-[myView]-(>=0)-|).这样做是为了限制在iPad上的宽度,所以在容器约束中存在宽度约束width <= 600 @1000中心水平.最重要的是,视图的宽高比约束为3:1.正如我所说,相当复杂.

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>
Run Code Online (Sandbox Code Playgroud)

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

_UITemporaryLayoutWidthconstaint来自哪里?显然我没有添加它.谷歌没有吐出任何有用的东西_UITemporaryLayoutWidth.有没有人遇到这样的问题?

tyl*_*ler 59

因此,我不确定这是否可以帮助您解决问题,因为它听起来像是在IB中构建您的布局,但这是我刚遇到的一个问题,可能有助于谷歌搜索"_UITemporaryLayoutWidth"的其他人.

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

更新:调查了一下,发现临时约束似乎对应于用于初始化父视图的框架.在我的例子中,我使用的帧大小为0x0,因此临时约束相对于0x0大小进行了评估,因此失败了.验证如果我使用5x5帧初始化,那么我会看到与_UITemporaryLayoutWidth(5)约束相同的错误.我注意到的另一件事是在布局评估期间似乎添加和删除了约束 - 如果我在触发布局之前断开并分析约束,那么我没有看到临时约束.我也没有看到错误后的约束,所以我怀疑他们合成了临时约束,添加它们,解决然后删除它们.

更新2:好的,也许这是TMI,但这可能对某人有用.我目前的想法是,这些临时约束可以看出系统如何在单个视图层次结构中处理混合帧操作和自动布局.在我的情况下,我的视图没有父级,没有约束来定义它的大小,但它确实有一个零帧,这意味着系统假设它是解决布局时应该使用的大小.我的想法是系统为视图合成这些临时约束,这些视图明确地设置了框架,以便在遍历层次结构时解决系统的其余部分.

更新3:所以,我再次遇到这个问题,并希望分享更多的信息.我的情况是我试图基本上使用systemLayoutSizeFittingSize:方法测量没有父级的视图.简而言之,我必须在测量之前在视图上调用layoutIfNeeded - 这是我遇到临时约束冲突的地方,因为视图没有超视图.临时约束常量(维度)确实对应于没有超视图的视图上设置的任何帧 - 我认为这是有道理的(但是,在将要与AutoLayout一起使用的视图上设置框架似乎很奇怪.. .)我能够解决临时约束问题 - 如果视图没有超视图,那么将其添加到临时超视图中; 测量; 从临时superview中删除它.希望这很有用.

  • ..."在将视图添加到视图层次结构之前意外触发'layoutIfNeeded'" - 谢谢你. (22认同)

Nic*_*ger 17

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

topView.translatesAutoresizingMaskIntoConstraints = false
Run Code Online (Sandbox Code Playgroud)


Rei*_*ner 11

我的情况,问题如下:

我创造了一个UIButton.
我设置了它的宽度和高度限制.
我将按钮添加到其超级视图中.
我将其主要和顶部布局约束设置为superview.

这创建了错误" Unable to simultaneously satisfy constraints",其中一个冲突的约束是_UITemporaryLayoutHeight.

当我设置宽度和高度约束之前将按钮添加到其超视图时,错误消失了.


xim*_*iao 8

在我的情况下,我只在这种情况下遇到了 UITemporaryLayoutWidth 冲突

  1. 我用 [UIView new] 创建了一个视图,但我没有将它添加到任何超级视图
  2. 然后我为这个视图创建了一个宽度约束刚刚被创建
  3. 立即调用 layoutIfNeeded 到此视图,并发生冲突

所以消除这个错误的方法很简单:在添加到一些超级视图之前不要调用 layoutIfNeeded


HAK*_*HAK 5

当我使用视图的布局边距锚点添加约束时,我遇到了这个问题。当我将约束从布局边距锚点更改为视图的顶部、底部、前导、尾随锚点时,错误消失了。

我正在用.zerorect 创建我的超级视图。

但由于我需要合并视图的边距,所以我不得不做一些修改。我改变了约束的优先级。

我遇到了临时宽度和临时高度错误。因此,我降低了沿水平轴的一个约束和沿垂直轴的一个约束的优先级(在本例中为顶部和尾随约束):

    let topConstraint = stackView.topAnchor.constraint(equalTo: margins.topAnchor)
    topConstraint.priority = .init(rawValue: 999.0)
    topConstraint.isActive = true

    let trailingConstraint = stackView.trailingAnchor.constraint(equalTo: margins.trailingAnchor)
    trailingConstraint.priority = .init(rawValue: 999.0)
    trailingConstraint.isActive = true
Run Code Online (Sandbox Code Playgroud)

原因是,由于我使用 .zero rect 初始化视图,iOS 会自动添加临时宽度和高度约束。这时如果我们添加其他高优先级的约束,就会中断错误日志的生成。

降低优先级可以修复破坏的约束,当临时约束被删除时,我们的视图将获得正确的形状。


Mat*_*uch 0

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

我对自动布局的内部了解不多,但我认为问题在于布局引擎如何满足约束的顺序。尺寸类别可能是添加临时宽度约束的原因。

不可满足的约束似乎并不是真正的问题,因为它们看起来只是暂时不可满足的。它只是每次创建视图时出现的几行日志。