3

在视觉格式语言中,有没有办法让两个元素在一个轴上保持相同的位置?

例如,我有一个UILabel和一个UITextField我想要水平并排的。在布置垂直约束时,无论如何都要指定这一点?

像这样的东西是理想的:

|-40-([label][field])-10-[otherStuff]

...其中[label][field]都具有相同的 Y 位置,但从超级视图顶部向下 40 点,在它们下方 10 点是[otherStuff]

这可能吗?

[label]或者我应该将and嵌套[field]在他们自己的 UIView 中,然后将其布置出来?

4

3 回答 3

2

视觉格式语言本身不支持这一点。首先,水平布局和垂直布局必须在两个单独的字符串中完成。但是+[NSLayoutConstraint constraintsWithVisualFormat:options:metrics:views:]可以选择包括对齐在内的选项。

所以,你可以使用:

NSDictionary* views = NSDictionaryOfVariableBindings(field, label);
NSArray* constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-40-[label]-10-[otherStuff]" options:0 metrics:nil views:views];
[field.superview addConstraints:constraints];
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"[label][field]" options:NSLayoutFormatAlignAllBaseline metrics:nil views:views];
[field.superview addConstraints:constraints];

在第二种情况下,这NSLayoutFormatAlignAllBaseline使得,不仅fieldtrail label,而且它们处于相同的垂直位置(基于它们的基线,这可能比对齐它们的中心、顶部或底部更好)。

于 2015-02-11T18:20:50.860 回答
1

可以这样想:如果您可以使用 Interface Builder 中的 Autolayout 来做到这一点,那么您也可以使用 Visual Format Language 来做到这一点。

但是,对于您建议的用例,您必须在多个语句中描述约束:

  1. field设置和的水平相同label
  2. 设置从 superview 顶部到字段的 40 px 垂直空间和 10 px 到otherStuff

总体上需要的是,对于每个子视图,所有 4 个必要的放置值(x、y、宽度和高度)都被明确定义。

我通过代码实现自动布局的一般方法是编写一个自定义库,其方法与 Interface Builder 中的单个约束所做的事情相同。以下是一些示例方法签名:

  1. +(void)addFixedHeightConstraintToView:(UIView*)view height:(CGFloat)height;
  2. +(void)addTopMarginFromSuperviewConstraintToView:(UIView*)view topMargin:(CGFloat)topMargin;
  3. +(void)addHorizontalSpaceConstraintFromView:(UIView*)fromView toView:(UIView*)toView horizontalSpace:(CGFloat)hSpace;

这些方法都是用非常简单易懂的 VFL 定义的。一旦有了这些,我就可以轻松解决您描述的用例。这是一些示例代码:

[CustomAutoLayout addTopMarginFromSuperviewConstraintToView:field topMargin:40];
[CustomAutoLayout addTopMarginFromSuperviewConstraintToView:label topMargin:40];
[CustomAutoLayout addHorizontalSpaceConstraintFromView:field toView:label horizontalSpace:0];
[CustomAutoLayout addVerticalSpaceConstrantFromView:field toView:otherStuff verticalSpace:10];
于 2015-02-11T17:15:12.620 回答
1

我知道的唯一方法是两个使用 2 视觉格式语句,如下所示:

|-40-[label]-10-[otherStuff]
|-40-[field]

不幸的是,这意味着复制第一条语句的一部分。

嵌套到另一个视图中是一种解决方案。

您还可以在不使用可视格式语言的情况下在代码中添加约束:

NSLayoutConstraint* fieldLeft = [NSLayoutConstraint constraintWithItem:field
           attribute:NSLayoutConstraintAttributeLeading
           relatedBy:NSLayoutRelationEqual 
           toItem:label 
           multiplier:1 constant:0];
[field.superview addConstraint:fieldLeft];
于 2015-02-11T17:50:10.163 回答