使用AutoLayout在UITableViewCell中垂直居中多个UILabel?

时间:2014-01-13 14:47:46

标签: ios objective-c autolayout nslayoutconstraint

我开始实现AutoLayout,我正在尝试拼凑我如何正确连接我的一个自定义UITableViewCell类。它通常有两个UILabel个对象,一个在另一个上面,很像标准的字幕类。我希望这两个标签在单元格中居中,无论单元格的高度如何,两者之间都有给定的填充。

我假设我可以通过添加两个标签的高度,添加填充,然后从单元格的高度减去它,然后除以2来做到这一点。但是,我在语义上很好奇这是否正确,因为我将它们限制在单元格的顶部和底部,而不是相互之间。我在这里错过了一招吗?

其次,有时候第三个标签也堆叠在一起,所以三个标签相互叠加。在那种情况下,我需要两组填充等,但问题变得更加相关:我不应该将它们相互约束,而不是限制在单元格的顶部和底部吗?

所以,问题更多的是语义问题:如果我想在父视图中垂直约束多个元素,有没有比我上面建议的方法更聪明的方法呢?

(我目前正在代码中完全实现AutoLayout(使用Masonry),因为这个单元格没有XIB而且不在故事板中。)

4 个答案:

答案 0 :(得分:25)

正确的方法是使用容器视图,该视图从其子视图中获取其高度。然后将容器视图固定到单元格的中心 - 您不会将容器链接到单元格的顶部和底部边缘。

在容器内,垂直约束为|[label1]-[label2]|,这将使容器成为两个标签的高度加上空间,容器视图的中心位于两个标签之间。

如果添加了三个标签,则为|[label1]-[label2]-[label3]|,容器的中心位于中间标签的中心。

在每种情况下,容器的中心都位于单元格的中心,您无需计算任何内容。

答案 1 :(得分:4)

使用Interface Builder ,我可以使用以下步骤垂直居中多个UIViews。我的用例是我希望这些多个UIView尽可能地像一个组一样行事,但我不想引入任何进一步的视图来实现它。

首先,我使用底部的按钮选择我认为是默认的Form Factor(Form Factor为3.5英寸或4英寸视网膜)。然后,我通过一次拖动按钮将按钮放在视图的中心,我使用蓝色指南的自动捕捉来帮助解决这个问题。

按钮就位后,我一次选择一个按钮来应用它们的约束。单击一个按钮,然后从Interface Builder右下角的浮动按钮中选择 Align Constraints 菜单(我看到一组4,而Align是左边的那个,旁边是Form Factor按钮)。

在此菜单中,选中容器中的垂直中心复选框,然后单击以打开该值旁边的下拉菜单,该值可能为0.从该列表中,选择使用当前画布值。然后,点击 Add Constraints 按钮(可能标记为 Add 1 Constraint )。

当你这样做时,如果你看到容器中的垂直中心旁边的值设置为你可能猜到的Y偏移值,你可能会知道它是有效的,只需回过头看看UIViews的安排。

如果您不想使用Interface Builder,请道歉,但我自己无法实现这一点,并想提及这些步骤。您可以始终将IB用作一次性,并以编程方式在测试中注销约束,然后将它们应用于仅代码解决方案中。

答案 2 :(得分:1)

假设您有label1label2label3cell

// Center the labels
[NSLayoutConstraint constraintWithItem:label1 attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual
                                toItem:cell.contentView attribute:NSLayoutAttributeCenterX
                            multiplier:1.0 constant:0]
[NSLayoutConstraint constraintWithItem:label2 attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual
                                toItem:cell.contentView attribute:NSLayoutAttributeCenterX
                            multiplier:1.0 constant:0]
[NSLayoutConstraint constraintWithItem:label3 attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual
                                toItem:cell.contentView attribute:NSLayoutAttributeCenterX
                            multiplier:1.0 constant:0]

// Vertical alignment/spacing of 8 between each label
[NSLayoutConstraint constraintWithItem:label1 attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual
                                toItem:cell.contentView attribute:NSLayoutAttributeTop
                            multiplier:1.0 constant:0]
[NSLayoutConstraint constraintWithItem:label2 attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual
                                toItem:label1 attribute:NSLayoutAttributeBottom
                            multiplier:1.0 constant:8]
[NSLayoutConstraint constraintWithItem:label3 attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual
                                toItem:label2 attribute:NSLayoutAttributeBottom
                            multiplier:1.0 constant:8]

您可以将所有内容嵌套在for()循环中,我猜您不必重复约束

答案 3 :(得分:1)

enter image description here 没有代码。只需在故事板中编辑。