使用视觉格式语言将视图置于其超级视图中
我刚开始学习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那里学到很多东西来回答这个问题。
是的,可以使用视觉格式语言将视图集中在其超视图中。 垂直和水平。 这里是演示:
我认为最好手动创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-muzyka在Swift中的答案:
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”。 没有需要的代码。