如何以编程方式在Auto Layout中拥有相同尺寸的多个标签?

时间:2017-04-05 14:12:37

标签: swift xcode autolayout

想象一下UITableView中的以下布局。红色区域为UILabel,蓝色区域为UITextField

enter image description here

我有以下限制让我开始:

    var allConstraints:[NSLayoutConstraint] = []

    allConstraints.append(NSLayoutConstraint(item: self.textFieldLabel!, attribute: .leading, relatedBy: .equal, toItem: self.textFieldLabel!.superview, attribute: .leadingMargin, multiplier: 1.0, constant: 0.0))
    allConstraints.append(NSLayoutConstraint(item: self.textFieldLabel!, attribute: .centerY, relatedBy: .equal, toItem: self.textFieldLabel!.superview, attribute: .centerY, multiplier: 1.0, constant: 0.0))
    allConstraints.append(NSLayoutConstraint(item: self.textField!, attribute: .leading, relatedBy: .equal, toItem: self.textFieldLabel!, attribute: .trailingMargin, multiplier: 1.0, constant: 0.0))
    allConstraints.append(NSLayoutConstraint(item: self.textField!, attribute: .trailing, relatedBy: .equal, toItem: self.textField!.superview, attribute: .trailingMargin, multiplier: 1.0, constant: 0.0))
    allConstraints.append(NSLayoutConstraint(item: self.textField!, attribute: .centerY, relatedBy: .equal, toItem: self.textField!.superview, attribute: .centerY, multiplier: 1.0, constant: 0.0))

    NSLayoutConstraint.activate(allConstraints)

但结果并不理想。红色标签占据了所有的空白。我在抓住自动布局工作方面有很多麻烦,任何人都可以帮助我吗?

编辑于2017年4月6日

当我使用以下行self.textFieldLabel!.setContentHuggingPriority(UILayoutPriorityDefaultHigh, for: .horizontal)添加内容时,我将得到以下结果。正如你所看到的那样,标签被切断了。

enter image description here

2 个答案:

答案 0 :(得分:2)

瞥一眼你的约束看起来很合理,我怀疑你缺少的是你的标签和文本字段的内容拥抱优先级。内容拥抱定义了视图的内在内容大小与适合其内容所需的最小内容相匹配的重要性。

因为两个视图可能具有相同的内容拥抱优先级(默认值为250)并且导致模糊的布局。标签的内在内容大小将是适合文本所需的宽度。空文本字段的内在内容大小为0.您的约束要求这两个视图一起跨越整个超级视图,但由于它们拥抱内容同样重要,因此它们是两个有效的布局:

  1. 标签只有所需的宽度,文本字段填充剩余的空间。
  2. 文本字段只有所需的宽度,标签填充剩余的空间。
  3. 您正在看到布局#2,但随时可能会切换,因为无法可靠地选择哪些内容拥抱大小优先,因为它们具有相同的优先级。

    您可以通过提高标签的内容拥抱优先级来解决此问题。如果标签的内容拥抱优先级大于文本字段的优先级,则明确哪个视图应首先填充可用空间是明确的;即我们告诉autolayout更重要的是保持视图的内容拥抱优先级较高。

    有关详情,请参阅Anatomy of a Constraint

答案 1 :(得分:0)

UILabels具有内在大小,基本上意味着如果定义相邻控件的前导/尾随锚点,它们的宽度将自动调整为仅适合其中的内容

Apple Doc on Intrinsic Size.

您可以执行所需操作的一种方法是为每个UILabel设置显式宽度。

另一种方式(几乎相同)是设置一个UILabel的宽度,并将剩余的UILabel左/右锚点设置为第一个UILabel的左/右锚点。

可能还有更多 - 包括使用UIStackViews等,但由于你已经完成了大部分的自动布局,前两个是最简单的。