动态的Label和Text Field高度
之前的例子中,通过假设text field的高度永远高于label的高度,我们简化了排版逻辑。然而事实上这个假定不一定一直是对的。当你将label的font size调大到一定程度,它就会扩张到text field上面。
接下来的例子将会在运行时动态地根据最高的控件来设定垂直空间。在使用一般情况的系统字体时,这个方法和之前的"简单的Label和Text Field"提到的一样(见截图)。然而如果你增加label的字体大小到36.0pt的话,排版中的垂直距离将会根据label的top计算得到。
这个例子或多或少是生造出来的。毕竟在一般情况下,如果你增加label的字体大小的话,你也会同时增加text field的字体大小。然而由于iPhone的无障碍设置中提供了“XXXL”字体大小的选项,这个技巧在混合了动态类型和固定大小控件(比如图片)的情况下很有用。
Views和Constraints
我们先建立和简单的Label和Text Field中一样的视图结构,但使用更加复杂的一系列constraints。
- Name Label.Leading = Superview.LeadingMargin
- Name Text Field.Trailing = Superview.TrailingMargin
- Name Text Field.Leading = Name Label.Trailing + Standard
- Name Label.Top >= Top Layout Guide.Bottom + 20.0
- Name Label.Top = Top Layout Guide.Bottom + 20.0 (Priority 249)
- Name Text Field.Top >= Top Layout Guide.Bottom + 20.0
- Name Text Field.Top = Top Layout Guide.Bottom + 20.0 (Priority 249)
- Name label.Baseline = Name Text Field.Baseline
属性
要让text field拉伸并充满可用空间,它的content hugging
必须要小于label的。默认情况下,interface builder应该会设置label的content hugging
为251,设置text field的content hugging
为250。你可以从size inspector验证这些。
Name | Horizontal hugging | Vertical hugging | Horizontal resistance | Vertical resistance |
---|---|---|---|---|
Name Label | 251 | 251 | 750 | 750 |
Name Text Field | 250 | 250 | 750 | 750 |
说明
上面的范例对每个控件都使用了一对constraints。一个必要的greater-than-or-equal(>=) constraints定义了控件和layout guide之间的最小距离,而一个可选的constraint试着将控件拉到距离layout guide正好20.0pt的地方。
对较高的控件来说,两个constraints都是可满足的,于是系统会将它放置在距离layout guide正好20pt的地方。然而,对矮一点的控件而言,只有最小距离constraint是可满足的。于是另外一个constraint被忽略了。这就能让控件变动时,Auto Layout系统动态地重新计算排版。
小贴士
必须确保可选的constraints的优先级数值低于content hugging constraint
的值(250)。否则系统会违反content hugging constraint,并且拉伸该View而不是重新定位它。
当和用了baseline对齐的layout一起使用时,这就会非常让人迷惑。因为baseline对齐只有在带文字的view以它们的固有高度显示时才有效。当系统调整其中一个view的大小时,文字可能不会被正确地排列,即便是设置了required baseline constraint。