使用可视格式语言在其超级视图中居中视图

Chr*_*orr 159 layout ios autolayout visual-format-language

我刚刚开始学习iOS的AutoLayout,并看了一下Visual Format Language.

这一切都很好,除了一件事:我只是无法在其超级视图中找到中心.
这可能与VFL有关,还是我需要自己手动创建约束?

lar*_*cus 231

目前,不,看起来不能使用VFL 将视图置于超视图中心.然而,使用单个VFL字符串和单个额外约束(每个轴)执行此操作并不困难:

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

[NSLayoutConstraint constraintWithItem:view
                             attribute:NSLayoutAttributeCenterX
                             relatedBy:NSLayoutRelationEqual
                                toItem:view.superview
                             attribute:NSLayoutAttributeCenterX
                            multiplier:1.f constant:0.f];
Run Code Online (Sandbox Code Playgroud)

有人会认为你只能做到这一点(这是我在看到这个问题时最初的想法和尝试):

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

我尝试了上面的许多不同变体试图将它弯曲到我的意愿,但即使明确地为两个轴(H:|V:)明确地具有两个单独的VFL字符串,这似乎也不适用于superview .然后,我开始尝试,准确地隔离时的选项得到应用的VFL.他们似乎并不适用于VFL的上海华盈,仅适用于(在某些情况下,令人失望的),它们在VFL字符串提到任何明确的意见.

我希望将来Apple增加了一些新的选项,让VFL选项考虑到superview,即使只在VFL中的superview之外只有一个显式视图时这样做.另一种解决方案可能是传递给VFL的另一种选择,例如:NSLayoutFormatOptionIncludeSuperview.

不用说,我学到了很多关于VFL试图回答这个问题的知识.

  • 下面的Evgeny的答案是有效的,因为autolayout引擎将`|`和`[superview]`视为单独的内部实体,即使它们代表相同的语义对象.通过使用`[superview]`,autolayout在其对齐度量中包含superview对象(在github链接的回答中,它是`NSLayoutFormatAlignAllCenterY` /`X`度量). (8认同)
  • 谢谢你的详细解答.然而,我使用VFL的唯一原因是摆脱那些丑陋的约束.太糟糕Apple还不支持这个...... (2认同)

Evg*_*nii 138

是的,可以使用Visual Format Language将视图置于其超视图中.垂直和水平.这是演示:

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

  • 这太棒了,你认为你可以扩展这个并解释它为什么有效吗? (15认同)
  • @Dan如果它对您不起作用,您可能还需要为宽度和高度设置约束.对于宽度,VFL就像这样:@"[label(== 200)]"和高度一样:@"V:[label(== 200)]" (4认同)
  • 我最终使用了更接近标记答案的东西,但是+1为您的github附件 (3认同)
  • 无法解析约束格式:选项掩码要在水平边缘上对齐的视图,对于也是水平的布局,不允许这样做.H:[上海华] - (<= 1) - [label1的] (3认同)

jqg*_*imo 82

我认为手动创建约束更好.

[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]];
Run Code Online (Sandbox Code Playgroud)

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

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

view.centerXAnchor.constraint(equalTo: superview.centerXAnchor).isActive = true
view.centerYAnchor.constraint(equalTo: superview.centerYAnchor).isActive = true
Run Code Online (Sandbox Code Playgroud)

我建议使用SnapKit,它是一个DSL,可以在iOS和macOS上轻松实现自动布局.

view.snp.makeConstraints({ $0.center.equalToSuperview() })
Run Code Online (Sandbox Code Playgroud)


Igo*_*yka 10

绝对有可能这样做:

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

这里学到了这一点. 上面的代码显然是Y中心的子视图.

Swift3:

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


Pan*_*kar 7

添加以下代码,并将您的按钮放在屏幕中央.绝对可能.

[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]];
Run Code Online (Sandbox Code Playgroud)