【问题标题】:UIStackView unsatisfiable autolayout constraintsUIStackView 无法满足的自动布局约束
【发布时间】:2018-12-05 16:48:05
【问题描述】:

我在故事板中定义了一个 UIStackView,第一个按钮的高度设置为 70,另一个设置为 45。我收到此自动布局错误:

 [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:0x280f614f0 UIButton:0x10641a120.height == 45   (active)>",
"<NSLayoutConstraint:0x280f60e60 UIButton:0x106418f80.height == 70   (active)>",
"<NSLayoutConstraint:0x280f604b0 'UISV-alignment' UIButton:0x10641a120.bottom == UIButton:0x106418f80.bottom   (active)>",
"<NSLayoutConstraint:0x280f63cf0 'UISV-alignment' UIButton:0x10641a120.top == UIButton:0x106418f80.top   (active)>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x280f60e60 UIButton:0x106418f80.height == 70   (active)>

我了解 UIStackView 无法接受不同高度的 UIButton,这是正确的吗?让 UIStackView 接受其元素的不同高度或宽度的方法是什么?

【问题讨论】:

    标签: ios autolayout uikit nslayoutconstraint uistackview


    【解决方案1】:

    堆栈视图约束中的某些内容导致了问题。

    这是一个有效的布局:

    使用堆栈视图属性:

    通过代码添加第三个按钮之前的结果:

    结果通过代码添加第三个按钮(高度限制为60):

    没有自动布局警告或错误。

    代码(连接到按钮 1),添加/删除 Button 3 作为堆栈视图的排列子视图:

    class TestViewController: UIViewController {
    
        @IBOutlet var theStackView: UIStackView!
    
        var thirdButton: UIButton = {
            let b = UIButton()
            b.translatesAutoresizingMaskIntoConstraints = false
            b.setTitle("Button 3", for: .normal)
            b.backgroundColor = .red
            return b
        }()
    
        @IBAction func doAddThird(_ sender: Any) {
    
            if theStackView.arrangedSubviews.count == 2 {
    
                theStackView.addArrangedSubview(thirdButton)
    
            } else {
    
                if let v = theStackView.arrangedSubviews.last {
                    v.removeFromSuperview()
                }
    
            }
    
        }
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            // finish initializing the third button
            if let v = theStackView.arrangedSubviews.first as? UIButton {
                thirdButton.titleLabel?.font = v.titleLabel?.font
            }
    
            NSLayoutConstraint.activate([
                thirdButton.heightAnchor.constraint(equalToConstant: 60),
                ])
    
        }   
    }
    

    【讨论】:

      【解决方案2】:

      如果您不给它高度和宽度限制,Stackview 将采用其组件的尺寸。看起来您正在告诉您的 stackView 是一个特定的高度(因为您有一个高度约束或两个暗示高度的 Y 位置约束)。除非这两个值完全相同,否则您不能既告诉 stackView 有一个高度,也不能告诉它的所有排列的Subviews 有一个高度。因此,例如,如果您告诉堆栈高 150,并且您的按钮高 45 和 70,那么具有最低内容拥抱优先级的按钮将丢失并被扩展以占用堆栈视图需要的额外 35 点空间高 150 分。

      快速解决方案:

      1. 移除堆栈视图的高度约束;它现在将与其元素高的总和一样高。
      2. 向堆栈添加一个空白 UIView 并将其内容拥抱为 1,它将占用任何额外空间(这仅在您的堆栈大于其元素时才有效;如果它太小,您需要减小安排子视图)。

      【讨论】:

      • stackview轴是水平的,所以约束中不需要指定单个元素的高度?
      • 那么您可能将对齐设置为 .fill 之类的东西,而需要 .top 或 .center 。 developer.apple.com/documentation/uikit/uistackview/alignment
      • 如果我指定 UIButtons 的高度和宽度,无论如何它都不会起作用。自动布局错误不断弹出。
      • 您需要为您的堆栈视图或创建它们的代码发布约束和属性。
      • 我没有对 UIStackView 设置任何约束。我所做的只是以编程方式在 UIStackView 中插入第三个 UIButton,它有两个高度为 60 的 UIButton。插入的按钮的宽度和高度约束设置为 45。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-15
      相关资源
      最近更新 更多