为什么自动布局对此布局有问题

Why does autolayout have issues with this layout

我在 Autolayout width 所有屏幕尺寸 上的键盘扩展遇到了一些问题。

起初它工作正常,但突然开始吐出一些错误,无论屏幕的宽度如何。我没有做任何更改,我什至尝试删除应用程序、清理项目并从头开始布置所有内容。

这是我的布局:

| - 8 - (50) - >=8 - (130) - 8 - (130) - 8 - |
priority (50) = 750, everything else = 1000

这不仅在 320 点4 英寸 屏幕上,而且在 屏幕上都会造成问题375 点4.7 英寸 屏幕和414 点5.5 英寸 屏幕。

据我所知,项目的最大宽度为 (8+50+8+130+8+130+8) 342 点。这小于 4.7 和 5.5 英寸 屏幕。在 4 英寸 上,我通过打破按钮 1 上的 50 点宽度来解决这个问题,所以总数是 320 点

它在模拟器和设备上看起来都不错,但是控制台吐出一些 Unable to simultaneously satisfy constraints 错误(准确地说是 3 个)。

这是日志:

1: (
"<NSLayoutConstraint:0x1740954a0 H:[UIButton:0x137e0cb80'Last sentence'(130)]>",
"<NSLayoutConstraint:0x1740955e0 H:[UIButton:0x137e0cda0'Pasteboard'(130)]>",
"<NSLayoutConstraint:0x174095810 H:|-(8)-[UIButton:0x137d0ba60]   (Names: '|':UIView:0x137e0c1b0 )>",
"<NSLayoutConstraint:0x1740958b0 H:[UIButton:0x137d0ba60]-(>=8)-[UIButton:0x137e0cda0'Pasteboard']>",
"<NSLayoutConstraint:0x174095950 H:[UIButton:0x137e0cda0'Pasteboard']-(8)-[UIButton:0x137e0cb80'Last sentence']>",
"<NSLayoutConstraint:0x1740959f0 H:[UIButton:0x137e0cb80'Last sentence']-(8)-|   (Names: '|':UIView:0x137e0c1b0 )>",
"<NSLayoutConstraint:0x170094ff0 'UIView-Encapsulated-Layout-Width' H:[UIView:0x137e0c1b0(55)]>"
)
Will attempt to recover by breaking constraint <NSLayoutConstraint:0x1740955e0 H:[UIButton:0x137e0cda0'Pasteboard'(130)]>

2: (
"<NSLayoutConstraint:0x1740954a0 H:[UIButton:0x137e0cb80'Last sentence'(130)]>",
"<NSLayoutConstraint:0x174095810 H:|-(8)-[UIButton:0x137d0ba60]   (Names: '|':UIView:0x137e0c1b0 )>",
"<NSLayoutConstraint:0x1740958b0 H:[UIButton:0x137d0ba60]-(>=8)-[UIButton:0x137e0cda0'Pasteboard']>",
"<NSLayoutConstraint:0x174095950 H:[UIButton:0x137e0cda0'Pasteboard']-(8)-[UIButton:0x137e0cb80'Last sentence']>",
"<NSLayoutConstraint:0x1740959f0 H:[UIButton:0x137e0cb80'Last sentence']-(8)-|   (Names: '|':UIView:0x137e0c1b0 )>",
"<NSLayoutConstraint:0x170094ff0 'UIView-Encapsulated-Layout-Width' H:[UIView:0x137e0c1b0(55)]>"
)
Will attempt to recover by breaking constraint <NSLayoutConstraint:0x1740954a0 H:[UIButton:0x137e0cb80'Last sentence'(130)]>

3: (
"<NSLayoutConstraint:0x174095810 H:|-(8)-[UIButton:0x137d0ba60]   (Names: '|':UIView:0x137e0c1b0 )>",
"<NSLayoutConstraint:0x1740958b0 H:[UIButton:0x137d0ba60]-(>=8)-[UIButton:0x137e0cda0'Pasteboard']>",
"<NSLayoutConstraint:0x174095950 H:[UIButton:0x137e0cda0'Pasteboard']-(8)-[UIButton:0x137e0cb80'Last sentence']>",
"<NSLayoutConstraint:0x1740959f0 H:[UIButton:0x137e0cb80'Last sentence']-(8)-|   (Names: '|':UIView:0x137e0c1b0 )>",
"<NSLayoutConstraint:0x170094ff0 'UIView-Encapsulated-Layout-Width' H:[UIView:0x137e0c1b0(0)]>"
)
Will attempt to recover by breaking constraint <NSLayoutConstraint:0x1740958b0 H:[UIButton:0x137d0ba60]-(>=8)-[UIButton:0x137e0cda0'Pasteboard']>

我整个晚上都在为这个问题绞尽脑汁。大家有什么建议吗?

如果我没记错的话...您的 "Pasteboard" 和 "Last Scentence" 按钮似乎有恒定的宽度和边距限制。

您对屏幕一侧的限制已经声明了宽度。因此,当自动布局运行时,它(可以理解)不知道要使用哪个约束。因此它打破了两个按钮的宽度限制并使用其他边距限制来设置宽度。

无论出于何种原因,父视图至少暂时只有 55 点宽。从您引用的日志中:

"<NSLayoutConstraint:0x174095810 H:|-(8)-[UIButton:0x137d0ba60]   (Names: '|':UIView:0x137e0c1b0 )>",
...
"<NSLayoutConstraint:0x1740959f0 H:[UIButton:0x137e0cb80'Last sentence']-(8)-|   (Names: '|':UIView:0x137e0c1b0 )>",
"<NSLayoutConstraint:0x170094ff0 'UIView-Encapsulated-Layout-Width' H:[UIView:0x137e0c1b0(55)]>"

因此,|(父视图的边缘)是 UIView:0x137e0c1b0,并且宽度限制为 55 点(UIView:0x137e0c1b0(55))。

该视图可能由框架控制。您需要适应它具有任意宽度(甚至是 0,如上一个例外)。为此,将其中一个水平间距约束设为非常高但不是必需的优先级,例如 950。这样,如果可能的话,它将保持不变,但如果必须的话,它会被打破而不会导致异常。显而易见的选择是对父视图后缘的约束。

超级视图比屏幕窄的情况大概是在视图层次结构被放在一起时,在显示之前。因此,当时允许打破约束不会影响任何实际可见的布局。