在可视化格式语言中,有一种方法可以将两个元素保持在一个轴上的相同位置吗?
例如,我有一个UILabel
和一个UITextField
,我想要水平地彼此并排。在布局垂直约束时,无论如何指定这个?
这样的事情是理想的:
|-40-([label][field])-10-[otherStuff]
...其中[label]
和[field]
都有相同的Y位置,但距离超级视图顶部40个点,而它们下面的10个点是[otherStuff]
。
这可能吗?
或者我应该将[label]
和[field]
嵌套在他们自己的UIView中,然后将其列出来?
答案 0 :(得分: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
使field
不仅label
跟踪{{1}},而且它们处于相同的垂直位置(基于它们的基线,即可能比对齐它们的中心,顶部或底部更好。
答案 1 :(得分:1)
以这种方式思考:如果你可以在Interface Builder中使用Autolayout来实现它,你也可以使用Visual Format Language来实现它。
但是,对于您建议的用例,您必须在多个语句中描述约束:
field
和label
otherStuff
所有需要的是,对于每个子视图,所有4个必要的放置值(x,y,宽度和高度)都是明确定义的。
我通过代码实现Autolayout的一般方法是编写一个自定义库,其方法与Interface Builder中的各个约束相同。以下是一些示例方法签名:
+(void)addFixedHeightConstraintToView:(UIView*)view height:(CGFloat)height;
+(void)addTopMarginFromSuperviewConstraintToView:(UIView*)view topMargin:(CGFloat)topMargin;
+(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];
答案 2 :(得分: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];