Swift - 具有零高度约束的 UIView - 错误

Posted

技术标签:

【中文标题】Swift - 具有零高度约束的 UIView - 错误【英文标题】:Swift - UIView with constraint of zero height - error 【发布时间】:2017-08-09 12:15:35 【问题描述】:

我有UIView 有高度限制。我想隐藏这个视图,所以我将高度约束常量设置为 0。

我在扩展 UIView 内的代码中设置约束:

_height = self.heightAnchor.constraint(equalToConstant: 50)

NSLayoutConstraint.activate([

        _closeBtn.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 5),
        _closeBtn.topAnchor.constraint(equalTo: self.topAnchor, constant: 10),
        _closeBtn.heightAnchor.constraint(equalTo: _centerLabel.heightAnchor),
        _closeBtn.widthAnchor.constraint(equalTo: _closeBtn.heightAnchor),

        _centerLabel.topAnchor.constraint(equalTo: self.topAnchor, constant: 10),
        _centerLabel.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -5),
        _centerLabel.leadingAnchor.constraint(equalTo: _closeBtn.trailingAnchor),
        _centerLabel.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -16),

        _height
    ])

现在,如果我更改 _height.constant = 0,我会收到此错误:

[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:0x146a374c0 UIButton:0x147615b00'X'.width == UIButton:0x147615b00'X'.height   (active)>",
    "<NSLayoutConstraint:0x146a37530 UIButton:0x147615b00'X'.height == UILabel:0x147615e80.height   (active)>",
    "<NSLayoutConstraint:0x146a37450 V:|-(20)-[UILabel:0x147615e80]   (active, names: '|':InternetConnectionInfoView:0x14742f600 )>",
    "<NSLayoutConstraint:0x146a373e0 UILabel:0x147615e80.bottom == InternetConnectionInfoView:0x14742f600.bottom - 5   (active)>",
    "<NSLayoutConstraint:0x146a37680 InternetConnectionInfoView:0x14742f600.height == 0   (active)>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x146a374c0 UIButton:0x147615b00'X'.width == UIButton:0x147615b00'X'.height   (active)>

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.

[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:0x146a37530 UIButton:0x147615b00'X'.height == UILabel:0x147615e80.height   (active)>",
    "<NSLayoutConstraint:0x146a37450 V:|-(20)-[UILabel:0x147615e80]   (active, names: '|':InternetConnectionInfoView:0x14742f600 )>",
    "<NSLayoutConstraint:0x146a373e0 UILabel:0x147615e80.bottom == InternetConnectionInfoView:0x14742f600.bottom - 5   (active)>",
    "<NSLayoutConstraint:0x146a37680 InternetConnectionInfoView:0x14742f600.height == 0   (active)>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x146a373e0 UILabel:0x147615e80.bottom == InternetConnectionInfoView:0x14742f600.bottom - 5   (active)>

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.

我怀疑这是因为顶部和底部锚点设置为恒定值。我曾尝试使用greaterThanOrEual / lessThanOrEqual,但它破坏了布局。

如何解决这个问题(例如隐藏 UIView)?我无法设置 isHidden,因为其他 UIView 锚定在此视图的底部,它们需要在隐藏时移动。

【问题讨论】:

我发现将UIView 的高度设为0 也意味着您需要将它的子视图isHidden 设置为true。你试过吗?编辑:我有一个视图是滑块的滑动菜单。它的动画效果很好 - 只需为子视图设置 isHidden,然后将主视图的高度设置为 0,然后对其进行动画处理。 @dfd 不工作,同样的错误 将其中一个约束的优先级更改为 999。 @Sulthan 是哪一个? 【参考方案1】:

这是一个约束冲突,考虑降低约束优先级可以帮助您解决这个问题。

let closeBtnTopAnchor = _closeBtn.topAnchor.constraint(greaterThanOrEqualTo: self.topAnchor)
let closeBtnTopAnchorWithLowPriority = _closeBtn.topAnchor.constraint(equalTo: self.topAnchor, constant: 10)
closeBtnTopAnchorWithLowPriority.priority = UILayoutPriorityDefaultHigh

let centerLabelTopAnchor = _centerLabel.topAnchor.constraint(greaterThanOrEqualTo: self.topAnchor)
let centerLabelTopAnchorWithLowPriority = _centerLabel.topAnchor.constraint(equalTo: self.topAnchor, constant: 10)
centerLabelTopAnchorWithLowPriority.priority = UILayoutPriorityDefaultHigh

let centerLabelBottomAnchor = _centerLabel.bottomAnchor.constraint(lessThanOrEqualTo: self.bottomAnchor)
let centerLabelBottomAnchorWithLowPriority = _centerLabel.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -5)
centerLabelBottomAnchorWithLowPriority.priority = UILayoutPriorityDefaultHigh

NSLayoutConstraint.activate([

   _closeBtn.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 5),
   closeBtnTopAnchor,
   closeBtnTopAnchorWithLowPriority,

   _closeBtn.heightAnchor.constraint(equalTo: _centerLabel.heightAnchor),
   _closeBtn.widthAnchor.constraint(equalTo: _closeBtn.heightAnchor),

   centerLabelTopAnchor,
   centerLabelTopAnchorWithLowPriority,
   centerLabelBottomAnchor,
   centerLabelBottomAnchorWithLowPriority,
   _centerLabel.leadingAnchor.constraint(equalTo: _closeBtn.trailingAnchor),
   _centerLabel.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -16),

   _height
   ])

【讨论】:

【参考方案2】:

如果隐藏 UIView 对你来说已经足够了,那么将其 alpha 设置为 0 怎么样?

【讨论】:

它不会移动锚点取决于可隐藏视图高度的视图。 哦,我明白了,那么您是否可以在 UIStackView 中使用这些视图?我只遇到过一次这样的情况,使用它解决了我的问题。 如果不是,则在将其设置为 0 时根据高度调整这些依赖约束应该可以工作,但我认为这可能是一种不好的做法。

以上是关于Swift - 具有零高度约束的 UIView - 错误的主要内容,如果未能解决你的问题,请参考以下文章

UIView 子类在 Swift 中设置自己的高度 + UIViewController 中的约束 + 情节提要

iOS:UIView 的 Autolayout 拉伸高度过多(Xcode 8、Swift 3)

UIView 内部约束

使用自动布局约束以编程方式创建四个具有相同高度和宽度的 UIView

如何在 Swift 中使用 SnapKit 使 UIView 具有相等的宽度和高度?

UIView的高度约束动画