无法同时满足约束 - LayoutConstraints

Posted

技术标签:

【中文标题】无法同时满足约束 - LayoutConstraints【英文标题】:Unable to simultaneously satisfy constraints - LayoutConstraints 【发布时间】:2019-07-14 12:32:33 【问题描述】:

我在TestViewController.swift 文件的代码隐藏中创建了一个按钮(myTestButton),正如您在我在帖子底部共享的源代码中看到的那样。旋转 Iphone(范围 2)后出现错误。为什么我会收到此错误?我该如何解决这个问题?

xcode中输出窗口的错误:

device has rotated! is landscape mode?: true
scope: 2
2019-07-14 15:23:14.411875+0300 myproject[12522:4008763] [LayoutConstraints] 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:0x28029b8e0 UIButton:0x103215110.centerY == UIView:0x103204e10.centerY   (active)>",
    "<NSLayoutConstraint:0x28028c550 UIButton:0x103215110.centerY == UIView:0x103204e10.centerY + 60   (active)>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x28028c550 UIButton:0x103215110.centerY == UIView:0x103204e10.centerY + 60   (active)>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.
2019-07-14 15:23:14.413028+0300 myproject[12522:4008763] [LayoutConstraints] 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:0x28029ba70 UIButton:0x103215110.width == UIView:0x103204e10.width - 20   (active)>",
    "<NSLayoutConstraint:0x28028c9b0 UIButton:0x103215110.width == UIView:0x103204e10.width - 40   (active)>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x28029ba70 UIButton:0x103215110.width == UIView:0x103204e10.width - 20   (active)>

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

这里是源代码:

import UIKit

class TestViewController: UIViewController 

var isOrientationStatusLandscape : Bool = false

let myTestButton : UIButton =

    let mytestbutton = UIButton()
    mytestbutton.backgroundColor = UIColor.yellow
    mytestbutton.translatesAutoresizingMaskIntoConstraints = false
    return mytestbutton
()

override func viewDidLoad() 
    super.viewDidLoad()
    self.setupView()


override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator) 
    if self.isOrientationStatusLandscape == true self.isOrientationStatusLandscape = false else self.isOrientationStatusLandscape = true
    print("device has rotated! is landscape mode?: \(self.isOrientationStatusLandscape)")
    self.setupView()


func setupView()

    self.prepareTheButton()


func prepareTheButton()

    view.addSubview(myTestButton)
    if isOrientationStatusLandscape == false
    
        print("scope: 1")
        myTestButton.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
        myTestButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        myTestButton.widthAnchor.constraint(equalTo: view.widthAnchor, constant: -20).isActive = true
        myTestButton.heightAnchor.constraint(equalToConstant: 120).isActive = true
    
    else
    
        print("scope: 2")
        myTestButton.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: 60).isActive = true
        myTestButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true

        myTestButton.widthAnchor.constraint(equalTo: view.widthAnchor, constant: -40).isActive = true
        myTestButton.heightAnchor.constraint(equalToConstant: 120).isActive = true
    


【问题讨论】:

因为当我们旋转时,您会添加新的约束,而不会删除您已经添加的约束。如果你旋转 10 次,那么这个可怜的小按钮将有 40 个约束。 明白。亲爱的@matt 你能给我写代码来删除现有的约束吗?然后我可以签名作为回复。谢谢。 【参考方案1】:

你需要创建2个数组

 let firstCons = [
     myTestButton.centerYAnchor.constraint(equalTo: view.centerYAnchor), 
     myTestButton.widthAnchor.constraint(equalTo: view.widthAnchor, constant: -20),
 ] 

 let secondCons = [
    myTestButton.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: 60), 
    myTestButton.widthAnchor.constraint(equalTo: view.widthAnchor, constant: -40), 
 ]

那就玩activate/deactivate

NSLayoutConstraint.deactivate(firstCons)
NSLayoutConstraint.activate(secondCons)

根据当前方向,顺便说一句,您可以排除 centerX 和 heightAnchor 约束以实现相似性

myTestButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true 
myTestButton.heightAnchor.constraint(equalToConstant: 120).isActive = true

【讨论】:

以上是关于无法同时满足约束 - LayoutConstraints的主要内容,如果未能解决你的问题,请参考以下文章

关闭:“无法同时满足约束”[重复]

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

如何解决无法同时满足约束

UITableViewCell - 无法同时满足约束

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

自动调整 UITableViewCell 大小:无法同时满足约束