以编程方式创建 UILabel 时出现的额外宽度和高度约束是什么?我怎样才能阻止他们的创造?

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

我以编程方式在我的应用程序中创建了 UI 元素,例如:

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()
}

UI标签正常创建和显示,但除了我的代码标签中的 3 个约束外,还有宽度和高度约束

调试视图层次结构截图:

在iOS模拟器截图中的应用:

调试控制台上的标签大小限制信息:

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

这里有宽度和高度约束是自动创建的,没有我的代码。我想阻止他们创建。

标签和父视图之间的约束:

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

在这里我们可以看到 3 个约束条件 UI 我的代码创建的标签和容器视图的系统约束条件以及 UIWindows

为什么会出现宽高限制?
我可以阻止他们创建吗?

您可以通过编程方式添加高度和宽度限制。但是你应该忽略(而不是添加)高度和宽度约束,如果你希望自动布局约束根据内容大小自动处理标签的高度和宽度。

高度限制:

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

宽度限制:

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

宽度约束对于右锚点意义不大,您已在代码中添加。您应该添加宽度约束或右锚点。

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

宽度约束将固定,标签的宽度,因此右锚点将失效。

我建议忽略高度和宽度限制(不要添加)。您在此处显示的代码(以及界面设计)对于 UIElement 的动态大小是正确的。 (如果您想添加任何其他 UIElement,您可以添加底部约束,相对于您当前的标签定位。)

更新:您的查询 - "I want to know why constraints missed in my code are appears and how can I prevent it."

我试过你的代码,它工作正常。 (您可以在代码中看到什么问题?)

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

这是结果:

这些约束已创建,因为 UILabel 具有 intrinsic content size。您可以使用 UILabel 上的内容压缩 (CHP) 和内容压缩抵抗 (CCRP) 优先级来影响这些约束。

它们将始终被创建,但如果您添加优先级高于 CHP / CCRP 的约束,那么您可以 'override' 在您的布局中添加它们。