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?

2

There are 2 best solutions below

0
On BEST ANSWER

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.

2
On

You can add height & width constraint programatically. But you should ignore (not add) height and width constraint, if you want autolayout constraint automatically handle, height and width of your label according to content size.

Height Constraint:

label.addConstraint(NSLayoutConstraint(item: label, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 20.0))

Width Constraint:

label.addConstraint(NSLayoutConstraint(item: label, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 20.0))

Width constraint is meaning less with right anchor, you have added in your code. Either you should add width constraint or right anchor.

 view.rightAnchor.constraint(greaterThanOrEqualTo: label.rightAnchor, constant: 20).isActive = true

Width constraint will fix, width of your label, hence right anchor will become ineffective.

I suggest ignore height and width constraint (do not add). Code you've shown here (as well as interface design) is correct for dynamic size of UIElement. (You can add bottom constraint if you want to add any other UIElement, positioned with respect to your current Label.)

Update: ( for your query - "I want to know why constraints missed in my code are appears and how can I prevent it.")

I tried your code and its working fine. (what's wrong that you can see in your code?)

 let label = UILabel()
    label.text = "Lorem Ipsum is simply dummy text of the printing and typesetting industry.  Lorem Ipsum has been the industry's standard dummy text ever since the 1500s. When an unknown printer took a galley of type and scrambled it n book."
    label.numberOfLines = 0
    label.lineBreakMode = .byTruncatingTail
    label.backgroundColor = UIColor.orange
    view.addSubview(label)

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

    view.layoutIfNeeded()

Here is result:

enter image description here