【问题标题】:Why do I receive an error that says 'Unable to simultaneously satisfy constraints.' for auto layout?为什么我会收到“无法同时满足约束条件”的错误消息。自动布局?
【发布时间】:2015-08-07 17:30:33
【问题描述】:

我正在尝试将一个按钮固定在所有 4 个侧面,以将按钮对象固定在我任意放置的确切位置,但是当我运行它时出现以下错误。任何见解或帮助将不胜感激。

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) 
(
"<_UILayoutSupportConstraint:0x9f494b0 V:[_UILayoutGuide:0x9f40370(20)]>",
"<_UILayoutSupportConstraint:0x9f3b6c0 V:|-(0)-[_UILayoutGuide:0x9f40370]   (Names: '|':UIView:0x9f3feb0 )>",
"<_UILayoutSupportConstraint:0x9f418e0 V:[_UILayoutGuide:0x9f407c0(0)]>",
"<_UILayoutSupportConstraint:0x9f18010 _UILayoutGuide:0x9f407c0.bottom == UIView:0x9f3feb0.bottom>",
"<NSLayoutConstraint:0x9f40f10 V:[UIButton:0x9f40f40'Button']-(211)-[_UILayoutGuide:0x9f407c0]>",
"<NSLayoutConstraint:0x9f47ab0 V:[_UILayoutGuide:0x9f40370]-(539)-[UIButton:0x9f40f40'Button']>",
"<NSLayoutConstraint:0xa157b10 'UIView-Encapsulated-Layout-Height' V:[UIView:0x9f3feb0(568)]>"
)

Will attempt to recover by breaking constraint 

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.

【问题讨论】:

  • 您的约束相互冲突。您可能想要发布您的 Interface Builder 视图的屏幕截图,因为更容易直观地确定您在哪里遇到了可能发生冲突的约束。 Interface Builder 有时可以作为 PITA 来处理,但一旦你“掌握了窍门”,它就会大大节省时间。
  • @AdrianB 对不起。刚刚上传了截图。所以我将一个按钮移动到视图中,并希望它位于那个确切的位置。如前所述,我固定了所有 4 个面,但得到了错误。将对象放置在您想要的确切位置的最佳方法是什么?谢谢!
  • 如果视图的大小发生变化,您预计会发生什么?
  • @AminNegm-Awad 抱歉,但不能安静地得到您的要求。能详细点吗?
  • @KoKi 我更新了我的答案。您遇到的错误并不是什么大问题——它只是告诉您存在冲突,Xcode 为您解决了它。对于您所拥有的,您只需将其固定在两侧,而不是 4 侧。或者,您可以尝试调整按钮的尺寸。

标签: ios objective-c debugging ios-autolayout


【解决方案1】:

即使@AdrianB在他的回答中对我的cmets有基本的了解,我将在这里详细解释:

假设视图的大小为 200 x 200,按钮为 100 x 20。(值仅用于示例)。所以我。例如,您将其放置在左侧空间 80、右侧空间 20 (80+100+20=200) 和顶部空间 100、底部空间 80 中。 (100+20+80=200)。

现在视图的大小发生了变化。它的宽度为 300。您对左右的约束仍然有效。所以边框仍然是 80 和 20。实现这一点的唯一方法是给按钮设置 200 的宽度。(80+200+20=300)。好的,也许是一个看起来很有趣的按钮,但这很有效。

但是,如果视图的高度变为 300,那么在垂直方向上确实变得很难。按钮必须在垂直方向上增长到 120。这是顶部和底部空间保持有效的唯一方法。我不认为按钮是那样的。

但是,当视图的高度小于 180 时,这是不可能的,因为所有空间都被您的约束 (top=100+bottom=80=180) 占用,因此底部不再有空间。它的高度变为负数。

这就是问题所在。

现在解决方法:

不要在自动布局中放置对所有四个边缘都具有硬约束的按钮。自动布局用于更改超级视图大小。在这种情况下,你所做的一切都是毫无意义的。

【讨论】:

  • 非常感谢您的详细解释。因此,在我试图实现的情况下,我应该怎么做才能解决它?如果我想把它放在那个确切的位置?
  • 首先您必须定义调整大小后的“确切”位置。这不是实施的问题,而是您想要的问题。但是,必须说明如果窗口调整大小会发生什么: 按钮向右、向左移动或改变其宽度。这是数学方式的唯一解决方案,您无法更改,因为您无法更改数学。垂直方向相同。
  • 明白!但是在我在图像中显示的情况下,我希望将其修复在相同的位置,即 iPhone 6 plus 视图的大小,并在 iPhone 6 的模拟上运行时将其显示在该确切位置加。我只是固定了底部和右侧,但是当我运行模拟时,它仍然在稍微不同的位置显示按钮。您将如何实现我所描述的目标?
  • 正如我所说:改变数学或做出决定。
  • 数学是指计算元素的点数和大小吗?如果是这样,我做到了,但它仍然没有解决我想要的问题。如果你不介意,你能指导我展示如何解决它吗?
【解决方案2】:

您收到该错误是因为您有相互冲突的约束。您可能需要删除 Interface Builder 中的一个约束来解决它。

我怀疑你可能是 iOS 新手,所以我建议你观看关于界面构建器的教程,而不是冗长冗长的答案。 Here's one from Ray Wenderlich你可能会觉得有帮助:

更新: 根据您的屏幕截图,我敢打赌您的按钮大小会导致问题。我认为固定在右侧和底部会平息控制台中记录的错误。在您的场景中没有其他项目的情况下,我认为您不需要顶部和左侧约束。

更新 2:

另一种方法是使用 >= 或 =,则底部约束将是 =,则右侧为

更新 3: 前往 iTunesU 观看 Stanford University's course titled CS193P, Winter 2015 的演示,Lecture 1 接近尾声。他在那次讲座中介绍了基本的自动布局。然后观看第 8 课,其中广泛介绍了自动布局。他在那里非常彻底地解释了一切。

对于自动布局,您使用的是 Swift 还是 Objective-C 并不重要。看到它的实际效果应该会让你明白一点。

【讨论】:

  • 我还没有硬编码任何东西,只是使用约束窗口并单击固定。我尝试仅固定右侧和底部,它确实显示在模拟中并且没有错误日志,但它不在故事板上最初位于的确切位置。此外,当我将屏幕旋转到不同的视图时,按钮就消失了。有没有办法解决这些问题?非常感谢您的帮助,阿德里安!
  • 我检查了,但我没有看到第 1 讲。它应该位于那个位置吗?谢谢!
【解决方案3】:

您不能有一个顶部距离为 539 点,底部距离为 211 点的按钮,即总共 750 点,不包括按钮高度。没有那种尺寸的 iPhone 屏幕,iPhone 6+ 的高度是 736 点,如果你要硬编码值,你应该调整按钮的 539、211 和高度,并确保它们加起来您正在调整大小的 iPhone 的屏幕高度。

这是一个宽度限制,等于 100 个点:

[self addConstraint:[NSLayoutConstraint constraintWithItem:_avatarImage
                                                         attribute:NSLayoutAttributeWidth
                                                         relatedBy:NSLayoutRelationEqual
                                                            toItem:nil
                                                         attribute:NSLayoutAttributeNotAnAttribute
                                                        multiplier:1.f
                                                          constant:100.f]];

这是一个宽度限制,等于 100 个点:

 [self addConstraint:[NSLayoutConstraint constraintWithItem:_avatarImage
                                                         attribute:NSLayoutAttributeHeight
                                                         relatedBy:NSLayoutRelationEqual
                                                            toItem:nil
                                                         attribute:NSLayoutAttributeNotAnAttribute
                                                        multiplier:1.f
                                                          constant:100.f]];

你也可以设置其他类型的约束,像这样,中心 x:

[self addConstraint:[NSLayoutConstraint constraintWithItem:_avatarImage
                                                 attribute:NSLayoutAttributeCenterX
                                                 relatedBy:NSLayoutRelationEqual
                                                    toItem:self
                                                 attribute:NSLayoutAttributeCenterX
                                                multiplier:1.f
                                                  constant:0.f]];

avatarImage 是一个 100x100 的图像视图,以超级视图中心 x 为中心,未显示 y 中心,但我对此也有限制。

这是我用来自动调整大小为 iphone 大小的一些宏,它基本上会根据最大视图(即 iphone 6+)自动调整所有视图的大小,我只为 iphone 6+ 设计,然后一切都通过,有时会出现一些异常情况,但这几乎涵盖了所有内容,包括使用混合自动布局和我自己的自定义布局引擎的程序化视图的所有内容。

#define SCREEN_WIDTH ((([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortrait) || ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortraitUpsideDown)) ? [[UIScreen mainScreen] bounds].size.width : [[UIScreen mainScreen] bounds].size.height)

#define SCREEN_HEIGHT ((([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortrait) || ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortraitUpsideDown)) ? [[UIScreen mainScreen] bounds].size.height : [[UIScreen mainScreen] bounds].size.width)

#define MAX_SCREEN_HEIGHT_IS_IPHONE6_PLUS 736.00
#define MAX_SCREEN_WIDTH_IS_IPHONE6_PLUS 414.00

#define heightResizer(n) n/MAX_SCREEN_HEIGHT_IS_IPHONE6_PLUS*SCREEN_HEIGHT
#define widthResizer(n) n/MAX_SCREEN_WIDTH_IS_IPHONE6_PLUS*SCREEN_WIDTH

所以,举个例子,看看这个约束:

 [self addConstraint:[NSLayoutConstraint constraintWithItem:_avatarImage
                                                         attribute:NSLayoutAttributeHeight
                                                         relatedBy:NSLayoutRelationEqual
                                                            toItem:nil
                                                         attribute:NSLayoutAttributeNotAnAttribute
                                                        multiplier:1.f
                                                          constant:100.f]];

现在,再看一遍:

 [self addConstraint:[NSLayoutConstraint constraintWithItem:_avatarImage
                                                         attribute:NSLayoutAttributeHeight
                                                         relatedBy:NSLayoutRelationEqual
                                                            toItem:nil
                                                         attribute:NSLayoutAttributeNotAnAttribute
                                                        multiplier:1.f
                                                          constant:heightResizer(100.0)]];

现在当 iPhone 尺寸小于 iPhone 6+ 时,hieght 会自动调整大小,这就是这个宏的美妙之处,你可以硬编码一些数字,而其他的你可以让自动布局引擎伸缩,这两种方法flex,两者都易于使用。导航栏高度和标签栏控制器高度会有一些问题,但如果你知道如何对这些 UI 元素进行子类化,那么它们就不再是问题了。我对所有内容进行子类化,甚至对我自己的子类进行子类化,因此使用这种混合布局形式可以使所有内容相互配合。

【讨论】:

  • 感谢您的评论。我的问题是,为什么 Xcode 不考虑对象的高度?那么约束中显示的数字,它们真正代表什么?我认为它们应该是从对象到所有 4 个侧面的视图边缘的空间。
  • 你是对的,你是错的,有些约束是针对上下左右的距离,有些是实际的高度和宽度限制,让我展示一下,但我不使用情节提要因为当您需要使用代码时很难知道该怎么做,请重新阅读我的答案
  • 在我想要达到的目标中,只是试图在那个位置修复那个按钮,对于所有 iPhone 设备,你会如何处理它?如果你不介意,你能简单描述一下吗?将不胜感激。我正要努力解决这么小的问题。
  • 非常感谢!你知道我在哪里可以看到它吗?
  • 好的,我会在大约一个小时后发布,
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-20
  • 1970-01-01
  • 1970-01-01
  • 2016-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多