【问题标题】:How does addSubview work with intrinsicSizes?addSubview 如何与intrinsicSizes 一起使用?
【发布时间】:2017-12-22 21:50:43
【问题描述】:

以下代码的结果是:我没有看到标签。

我的理解是标签的 intrinsicSize 将允许标签拉伸。为什么没有发生这种情况?

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        view.addSubview(label)
    }

    let label : UILabel = {
        let label = UILabel()
        label.text = "How are you doing today my friend"
        label.backgroundColor = .orange

        return label
    }()
}

【问题讨论】:

  • 标签没有设置框架布局或自动布局
  • @Sh_Khan 基于Auto Layout Guide,intrinsicSize。请参阅清单 3-5 抗压缩和内容拥抱方程。 IntrinsicSize 生成约束...即使我将translatesAutoresizingMaskIntoConstraints 设置为false 我仍然得到相同的结果...
  • 检查布局调试器,看看它的位置和框架是什么。
  • @JustinM 我已经这样做了,显然帧是 0,0,0,0
  • 您没有设置任何约束。自动布局将使用固有大小,但您仍然需要给它一些您想要标签的线索

标签: ios swift uiview addsubview intrinsic-content-size


【解决方案1】:

这个:

let label = UILabel()

(0, 0) 处创建一个标签,其宽度为0,高度为0。默认情况下,iOS 将从frame 为标签的位置、宽度和高度创建约束。

如果您想使用标签的固有大小,请禁用从框架创建约束并提供标签约束以将其放置在视图中。

例如(将标签添加为子视图后):

label.translatesAutoresizingMaskIntoConstraints = false
label.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
label.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true

或者您可以在创建框架时使用label.intrisicContentSize

label.frame = CGRect(origin: CGPoint(x: 40, y: 100), size: label.intrinsicContentSize)

注意:如果您使用label.intrinsicSize 设置frame,则frame 在您更改标签文本时不会更改。您必须再次更新它:

label.frame.size = label.intrinsicContentSize

更改label.text后。


实际上,Auto Layout 为标签的instrinsicContentSize 创建了 4 个约束,但这些约束的优先级低于从 frame 创建的约束,因此它们不起作用。通过禁用从frame 创建约束,您可以让较低优先级的instrinsicContentSize 约束有机会影响UILabel 的布局。

您可以在标题为内在内容大小的部分中的Apple's Auto Layout Guide 中详细了解这一点。

【讨论】:

  • "在 (0, 0) 处创建一个宽度为 0 高度为 0 的标签。"正确的。那么居中如何给它一个高度和宽度呢?对我来说,它应该只改变 x 和 y... 您对 label.intrinsicContentSize 的使用非常棒。我真的很喜欢。
  • Auto Layout 使用intrinsicContentSize 为其提供宽度和高度,如果您没有明确指定宽度和高度的约束。
  • 没有。 Auto Layout 的算法是:如果标签的宽度和高度没有用约束指定,则使用固有的内容大小。设置 label.translatesAutoresizingMaskIntoConstraints = false 会移除系统为您创建的 4 个约束,并使所有内容不受约束。通过指定标签的位置,iOS 从intrinsicContentSize 中计算出宽度和高度。
  • @Honey,我写的稍微复杂一些。系统会为intrinsicContentSize 创建约束,但这些约束的优先级较低,如果它们被更高优先级的约束压倒,它们将不起作用。默认情况下从框架创建的约束具有高优先级,因此它们不会给 instrinsicContentConstraints 工作机会。通过禁用从框架创建的约束,较低优先级的 intrinsicContentConstraits 有机会工作。
  • 如果您覆盖 viewDidLayoutSubviewsprint(view.constraints.count)print(label.constraints.count),如果您只设置 label.translatesAutoresizingMaskIntoConstraints = false,您将看到有 0 约束。但是,一旦您设置了 Y 位置约束,这些计数就会转到 525 是 4 个 instrinsicContentSize 约束加上 Y 位置约束。 2 是标签宽度和高度的约束。
【解决方案2】:

它是内在内容大小而不是内在内容位置保证为标签提供宽度和高度如果它没有严格地具有可能修剪其内容的前导和尾随约束,但至少您必须通过框架布局或自动布局但要设置

  translatesAutoresizingMaskIntoConstraints to false

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-02
    • 1970-01-01
    • 2016-08-27
    相关资源
    最近更新 更多