使用视觉格式语言将视图置于其超级视图中

我刚开始学习iOS的AutoLayout,看看Visual Format Language。

除了一件事情之外,这一切都很好:我只是无法看到它的超级视图中心。
这是可能的VFL或者我需要自己手动创build一个约束?

目前,不,看起来好像只能使用VFL在超级视图中居中。 然而,使用单个VFLstring和单个额外约束(每个轴)来执行它并不困难:

VFL: "|-(>=20)-[view]-(>=20)-|"

 [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:view.superview attribute:NSLayoutAttributeCenterX multiplier:1.f constant:0.f]; 

人们会认为你可以简单地做到这一点(当我看到这个问题时,这就是我最初想到和尝试的):

 [NSLayoutConstraint constraintsWithVisualFormat:@"|-(>=20)-[view(==200)]-(>=20)-|" options: NSLayoutFormatAlignAllCenterX | NSLayoutFormatAlignAllCenterY metrics:nil views:@{@"view" : view}]; 

我尝试了许多不同的变体,尝试将其弯曲到我的意愿,但是,即使明确地为两个轴( H:|V: :)显式地使用两个单独的VFLstring,也不会将其应用于超视图。 然后,我开始尝试隔离到什么时候选项适用于VFL。 它们似乎不适用于VFL中的超级观点,只适用于VFLstring中提到的任何明确的观点(在某些情况下令人失望)。

我希望在未来,苹果增加了一些新的选项,让VFL选项考虑到超级视图,即使只有在除了VFL中的超级视图之外只有一个明确的视图时才会这样做。 另一种解决scheme可能是传递给VFL的另一个选项,如下所示: NSLayoutFormatOptionIncludeSuperview

不用说,我从VFL那里学到很多东西来回答这个问题。

是的,可以使用视觉格式语言将视图集中在其超视图中。 垂直和水平。 这里是演示:

https://github.com/evgenyneu/center-vfl

我认为最好手动创build约束。

 [superview addConstraint: [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:superview attribute:NSLayoutAttributeCenterX multiplier:1 constant:0]]; [superview addConstraint: [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:superview attribute:NSLayoutAttributeCenterY multiplier:1 constant:0]]; 

现在我们可以使用NSLayoutAnchor以编程方式定义AutoLayout:

(适用于iOS 9.0及更高版本)

 view.centerXAnchor.constraint(equalTo: superview.centerXAnchor).isActive = true view.centerYAnchor.constraint(equalTo: superview.centerYAnchor).isActive = true 

我build议使用SnapKit ,这是一种DSL,可以使iOS和MacOS上的Auto Layout变得更加简单。

 view.snp.makeConstraints({ $0.center.equalToSuperview() }) 

绝对有可能是这样做的:

 [NSLayoutConstraint constraintsWithVisualFormat:@"H:[view]-(<=1)-[subview]" options:NSLayoutFormatAlignAllCenterY metrics:nil views:NSDictionaryOfVariableBindings(view, subview)]; 

从这里了解到这一点。 上面的代码显然是由Y中的子视图来看的。

Swift3:

  NSLayoutConstraint.constraints(withVisualFormat: "H:[view]-(<=1)-[subview]", options: .alignAllCenterY, metrics: nil, views: ["view":self, "subview":_spinnerView]) 

添加下面的代码,让你的button在屏幕的中心。 绝对有可能。

 [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[button]-|" options:NSLayoutFormatAlignAllCenterY metrics:0 views:views]]; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[button]-|" options:NSLayoutFormatAlignAllCenterX metrics:0 views:views]]; 

我知道这不是你想要的,但你当然可以计算边距,并使用它们来创build视觉格式string;)

无论如何,不​​。 不幸的是,VFL不可能“自动”做 – 至less现在还不行。

感谢@Evgenii的回答,我创build了一个完整的例子:

以定制高度垂直居中红色方块

https://gist.github.com/yallenh/9fc2104b719742ae51384ed95dcaf626

您可以通过使用VFL(不太直观)或手动使用约束来垂直居中视图。 顺便说一下,我不能把VFY中的Y和Y都结合在一起,例如:

 "H:[subView]-(<=1)-[followIcon(==customHeight)]" 

在当前的解决scheme中,VFL约束分别添加。

必须要做的是应该在字典中声明superview。 而不是使用| 你使用@{@"super": view.superview};

NSLayoutFormatAlignAllCenterX垂直和NSLayoutFormatAlignAllCenterY水平作为选项。

您可以使用额外的意见。

 NSDictionary *formats = @{ @"H:|[centerXView]|": @0, @"V:|[centerYView]|": @0, @"H:[centerYView(0)]-(>=0)-[yourView]": @(NSLayoutFormatAlignAllCenterY), @"V:[centerXView(0)]-(>=0)-[yourView]": @(NSLayoutFormatAlignAllCenterX), }; NSDictionary *views = @{ @"centerXView": centerXView, @"centerYView": centerYView, @"yourView": yourView, }; ^(NSString *format, NSNumber *options, BOOL *stop) { [superview addConstraints: [NSLayoutConstraint constraintsWithVisualFormat:format options:options.integerValue metrics:nil views:views]]; }]; 

如果你想要整齐,那么centerXView.hidden = centerYView.hidden = YES;

PS:我不确定我可以打多余的意见“占位符”,因为英语是我的第二语言。 如果有人能告诉我,将不胜感激。

对于那些来到这里的基于Interface Builder的解决scheme(谷歌带领我在这里),只需添加常量宽度/高度的约束,并select子视图 – >控制拖到它的超级视图 – >select“垂直/水平在超视图中心”。

@ igor-muzykaSwift中的答案:

 NSLayoutConstraint.constraintsWithVisualFormat("H:[view]-(<=1)-[subview]", options: .AlignAllCenterY, metrics: nil, views: ["view":view, "subview":subview]) 

只需要说,你可以使用这个而不是约束:

 child.center = [parent convertPoint:parent.center fromView:parent.superview]; 

而不是使用VFL,你可以很容易地在界面生成器中做到这一点。 在主要故事板中,按住Ctrl并点击您想居中的视图。 拖动到超级视图(按住Ctrl键)并select“中心X”或“中心Y”。 没有需要的代码。

Interesting Posts