Martin Perry
Martin Perry

Reputation: 9527

Swift - UIView with constraint of zero height - error

I have UIView with height constraint. I want to hide this view, so I set height constraint constant to 0.

I am setting constraint in code inside extended 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
    ])

Now, If I change _height.constant = 0, I have got this error:

[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.

I suspect, that this comes from top and bottom anchor being set to constant values. I have tried to use greaterThanOrEual / lessThanOrEqual, but it destroys the layout.

How to solve this (eg. hiding UIView)? I cannot set isHidden, because other UIViews are anchored to the bottom of this view and they need to move upon hiding.

Upvotes: 2

Views: 2644

Answers (2)

Zhang
Zhang

Reputation: 394

This is a constraint conflict, consider reducing the constraint priority can help you fix this issue.

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
   ])

Upvotes: 1

Mango
Mango

Reputation: 187

If hiding the UIView is enough for you, how about setting its alpha to 0 ?

Upvotes: 0

Related Questions