使用代码创建约束 - 出现错误“无法同时满足约束”[重复]

Posted

技术标签:

【中文标题】使用代码创建约束 - 出现错误“无法同时满足约束”[重复]【英文标题】:Create constraints with code - getting error "Unable to simultaneously satisfy constraints" [duplicate] 【发布时间】:2016-07-18 21:06:46 【问题描述】:

我在情节提要中添加了一个 UIView(称为 swipedView),但我没有对其设置任何自动布局约束。没有。现在在代码中,我想添加一些约束。为了测试它,我想把它固定在屏幕的两侧(所以它是全屏的)。

当我运行它时,我会收到一条很长的错误消息,例如:

2016-07-18 22:59:07.990 FindTheWay[87145:18423835] 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. 
(
    "<NSLayoutConstraint:0x7ff02d11a6e0 V:|-(0)-[UIView:0x7ff02b479a40]   (Names: '|':UIView:0x7ff02b450100 )>",
    "<NSIBPrototypingLayoutConstraint:0x7ff02b416a50 'IB auto generated at build time for view with fixed frame' V:|-(20)-[UIView:0x7ff02b479a40]   (Names: '|':UIView:0x7ff02b450100 )>"
)

Will attempt to recover by breaking constraint 
<NSIBPrototypingLayoutConstraint:0x7ff02b416a50 'IB auto generated at build time for view with fixed frame' V:|-(20)-[UIView:0x7ff02b479a40]   (Names: '|':UIView:0x7ff02b450100 )>

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.

那是我的视图控制器

import UIKit

class ViewController: UIViewController 

    @IBOutlet weak var swipedView: UIView!
    @IBOutlet weak var foregroundView: UIView!
    override func viewDidLoad() 
        super.viewDidLoad()
        // that was a proposed fix to my problem I found in the internet. Didn't work
        view.translatesAutoresizingMaskIntoConstraints = false

    

    override func viewDidAppear(animated: Bool) 

        let pinTop = NSLayoutConstraint(item: swipedView, attribute: .Top, relatedBy: .Equal, toItem: view, attribute: .Top, multiplier: 1.0, constant: 0)
        let pinLeft = NSLayoutConstraint(item: swipedView, attribute: .Leading, relatedBy: .Equal, toItem: view, attribute: .Leading, multiplier: 1.0, constant: 0)
        let pinRight = NSLayoutConstraint(item: swipedView, attribute: .Trailing, relatedBy: .Equal, toItem: view, attribute: .Trailing, multiplier: 1.0, constant: 0)
        let pinBottom = NSLayoutConstraint(item: swipedView, attribute: .Bottom, relatedBy: .Equal, toItem: view, attribute: .Bottom, multiplier: 1.0, constant: 0)

        NSLayoutConstraint.activateConstraints([pinTop, pinLeft, pinRight, pinBottom])

    

    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
        

我对通过代码设置约束完全陌生,所以我不确定如何处理这个问题。我检查了我在 *** 上发现的几个类似问题,但不幸的是,这里没有任何帮助。

【问题讨论】:

试过了。虽然我没有找到这样的功能,只有一个布尔值设置为false 您尝试过接受的答案链接到的关于NSIBPrototypingLayoutConstraint 的内容? 我也试过了,是的。现在它起作用了(我不得不改变一些东西,见 ZGski 的回答)。我不知道为什么。我来回答一下 【参考方案1】:

swipedViewtranslatesAutoresizingMaskIntoConstraints 设置为false,而不是view

import UIKit

class ViewController: UIViewController 

    @IBOutlet weak var swipedView: UIView!
    @IBOutlet weak var foregroundView: UIView!
    override func viewDidLoad() 
        super.viewDidLoad()
        // that was a proposed fix to my problem I found in the internet. Didn't work
        swipedView.translatesAutoresizingMaskIntoConstraints = false

    

    override func viewDidAppear(animated: Bool) 

        let pinTop = NSLayoutConstraint(item: swipedView, attribute: .Top, relatedBy: .Equal, toItem: view, attribute: .Top, multiplier: 1.0, constant: 0)
        let pinLeft = NSLayoutConstraint(item: swipedView, attribute: .Leading, relatedBy: .Equal, toItem: view, attribute: .Leading, multiplier: 1.0, constant: 0)
        let pinRight = NSLayoutConstraint(item: swipedView, attribute: .Trailing, relatedBy: .Equal, toItem: view, attribute: .Trailing, multiplier: 1.0, constant: 0)
        let pinBottom = NSLayoutConstraint(item: swipedView, attribute: .Bottom, relatedBy: .Equal, toItem: view, attribute: .Bottom, multiplier: 1.0, constant: 0)

        NSLayoutConstraint.activateConstraints([pinTop, pinLeft, pinRight, pinBottom])

    

    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    


这个解决方案最终起作用的原因可以在Apple's Documentation中找到。

请注意,自动调整掩码约束完全指定了视图的大小和位置;因此,您不能添加额外的约束来修改此大小或位置而不引入冲突。

translatesAutoresizingMaskIntoConstraints 设置为true 时,我们是说我们希望相关视图的大小和位置变成实际的约束。

通过将translatesAutoresizingMaskIntoConstraints 设置为false,我们是说相关视图的大小和位置不应以任何原因变成约束(在这种情况下,我们正在创建自己的)。

由于我们不是希望应用修改view 的大小和位置的约束,但实际上是swipedView,我们需要将swipedViewtranslatesAutoresizingMaskIntoConstraints 设置为相等到false

【讨论】:

【参考方案2】:

我在使用界面生成器时遇到了同样的问题,解决方案是识别导致警告的约束(在这种情况下可能一次注释掉一个),然后将该约束的优先级设置为999 而不是 1000(我认为这是默认值)。以编程方式,您可以这样做:

constraint.priority = 999

(用任何受影响的约束替换“约束”。) 这对我有用几次并且不会影响布局,但会清除警告。我认为 999 相当于说“尽可能接近,但不要担心”,所以如果约束未能满足一小部分,你就不会收到警告。希望有帮助。

【讨论】:

谢谢,但问题是每一个约束都导致了这个错误(我试着把它们一个一个注释掉)。【参考方案3】:

使用本文中提到的技术: http://travisjeffery.com/b/2013/11/preventing-ib-auto-generated-at-build-time-for-view-with-fixed-frame-when-using-auto-layout/

它对我不起作用的原因是我犯的错误

view.translatesAutoresizingMaskIntoConstraints = false

应该是的

swipedView.translatesAutoresizingMaskIntoConstraints = false

现在可以了。我不知道为什么(也许有人可以解释一下?)

感谢@ZGski 和@dan

【讨论】:

如果我提供的答案最终起到了作用,您介意将其标记为已接受吗 我不确定,因为如果不在情节提要中添加这些约束(并在运行时删除它们),您的答案将不起作用。这是两者的结合。考虑到这些事情的规则对***非常严格,所以我不确定。编辑:如果您可以将此添加到您的答案中,我很乐意将其标记为正确答案:)

以上是关于使用代码创建约束 - 出现错误“无法同时满足约束”[重复]的主要内容,如果未能解决你的问题,请参考以下文章

UITableViewCell - 无法同时满足约束

存在 UIToolbarContentView 时无法同时满足约束

iOS - AutoLayout'无法同时满足约束'

Swift4 - 我第一次无法显示 CollectionView “无法同时满足约束”

UIAlertview 错误:无法同时满足约束

无法同时满足约束