iosswiftlabelnslayoutconstraintlayout-anchor

What the extra width and height constraints appears at programmatically creating UILabel? And how can I prevent theirs creating?


I creates UI element in my application programmatically, eg:

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    let label = UILabel()
    label.text = "Just text"
    label.backgroundColor = #colorLiteral(red: 0.721568644, green: 0.8862745166, blue: 0.5921568871, alpha: 1)
    view.addSubview(label)

    label.translatesAutoresizingMaskIntoConstraints = false
    label.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 20).isActive = true
    label.topAnchor.constraint(equalTo: view.topAnchor, constant: 20).isActive = true
    view.rightAnchor.constraint(greaterThanOrEqualTo: label.rightAnchor, constant: 20).isActive = true

    view.layoutIfNeeded()
}

UILabel creates and appears normally, but besides 3 constraints from my code label has also width and height constraints

Debug view hierarchy screenshot: Extra constraints

Application in iOS simulator screenshot: iOS Simulato screenshot

Label size constraints info at debug console:

po ((UIView *)0x7f8573c0ccc0).constraints
<__NSArrayI 0x600000236820>(
<NSContentSizeLayoutConstraint:0x6000000a8b20 UILabel:0x7f8573c0ccc0'Just text'.width == 66 Hug:250 CompressionResistance:750   (active)>,
<NSContentSizeLayoutConstraint:0x6000000a8b80 UILabel:0x7f8573c0ccc0'Just text'.height == 20.3333 Hug:250 CompressionResistance:750   (active)>
)

There are width and height constraint here that was created automatically, without my code. I want to prevent theirs creating.

Constraints between label and superview:

po ((UIView *)((UIView *)0x7f8573c0ccc0).superview).constraints
<__NSArrayI 0x60000028c3f0>(
<NSLayoutConstraint:0x600000284a60 H:|-(20)-[UILabel:0x7f8573c0ccc0'Just text'](LTR)   (active, names: '|':UIView:0x7f8573c0b7b0 )>,
<NSLayoutConstraint:0x6000002854b0 V:|-(20)-[UILabel:0x7f8573c0ccc0'Just text']   (active, names: '|':UIView:0x7f8573c0b7b0 )>,
<NSLayoutConstraint:0x600000285550 H:[UILabel:0x7f8573c0ccc0'Just text']-(>=20)-|(LTR)   (active, names: '|':UIView:0x7f8573c0b7b0 )>,
<NSLayoutConstraint:0x600000285cd0 'UIView-Encapsulated-Layout-Height' UIView:0x7f8573c0b7b0.height == 736   (active)>,
<NSAutoresizingMaskLayoutConstraint:0x600000285d70 h=-&- v=-&- 'UIView-Encapsulated-Layout-Left' UIView:0x7f8573c0b7b0.minX == 0   (active, names: '|':UIWindow:0x7f8573d132d0 )>,
<NSAutoresizingMaskLayoutConstraint:0x600000285eb0 h=-&- v=-&- 'UIView-Encapsulated-Layout-Top' UIView:0x7f8573c0b7b0.minY == 0   (active, names: '|':UIWindow:0x7f8573d132d0 )>,
<NSLayoutConstraint:0x600000285c80 'UIView-Encapsulated-Layout-Width' UIView:0x7f8573c0b7b0.width == 414   (active)>
)

Here we can look 3 constraints with UILabel created by my code and system constraints with container view and UIWindows

Why width and height constraint was appeared?
And can I prevent theirs creating?


Solution

  • Those constraints are created, because a UILabel has an intrinsic content size. You can influence those constraints using the content hugging (CHP) and content compression resistance (CCRP) priorities on the UILabel.

    They will always be created, but if you add constraints with priorities higher than the CHP / CCRP, then you can 'override' them in your layout.