2

我以编程方式在我的应用程序中创建 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()
}

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

调试视图层次截图: 额外的约束

iOS模拟器中的应用截图: 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)>
)

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

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

在这里,我们可以查看由我的代码创建的带有 UILabel 的 3 个约束以及带有容器视图和 UIWindows 的系统约束

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

4

2 回答 2

1

这些约束被创建,因为 UILabel 具有内在的内容大小。您可以使用 UILabel 上的内容拥抱 (CHP) 和内容压缩阻力 (CCRP) 优先级来影响这些约束。

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

于 2017-10-17T00:03:03.210 回答
0

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

高度限制:

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,则可以添加底部约束。)

更新:(对于您的查询 - “我想知道为什么会出现我的代码中遗漏的约束以及如何防止它。”

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

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

这是结果:

在此处输入图像描述

于 2017-10-11T11:32:11.740 回答