161

iOS の AutoLayout の学習を始めたばかりで、Visual Format Language を調べました。

1 つのことを除いて、すべて正常に動作します。スーパービュー内でビューを中央に配置できません。
これは VFL で可能ですか、それともコンストレイントを自分で手動で作成する必要がありますか?

4

14 に答える 14

232

現在、いいえ、 VFLのみを使用してスーパービューでビューを中央に配置することはできないようです。ただし、1 つの VFL 文字列と 1 つの追加のコンストレイン (軸ごと) を使用することはそれほど難しくありません。

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}];

上記のさまざまなバリエーションを試してみましたが、両方の軸に 2 つの個別の VFL 文字列を明示的に指定した場合でも、スーパービューには適用されないようです ( H:|V:)。次に、オプションがVFL に適用されるタイミングを正確に特定しようと試みました。それらは VFL のスーパービューには適用されないようで、VFL 文字列で言及されている明示的なビューにのみ適用されます (これは場合によっては期待外れです)。

将来的には、VFL のスーパービュー以外に明示的なビューが 1 つしかない場合にのみ行う場合でも、VFL オプションでスーパービューを考慮に入れるための新しいオプションが Apple に追加されることを願っています。別の解決策は、次のような VFL に渡される別のオプションである可能性がありますNSLayoutFormatOptionIncludeSuperview

言うまでもなく、私はこの質問に答えようとして VFL について多くのことを学びました。

于 2012-10-30T21:44:09.160 に答える
139

はい、Visual Format Language を使用してビューをスーパービューの中央に配置することができます。縦にも横にも。デモは次のとおりです。

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

于 2013-02-17T03:31:24.300 に答える
83

手動で制約を作成する方が良いと思います。

[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

iOS と macOS の両方で自動レイアウトを簡単にする DSL であるSnapKitを使用することをお勧めします。

view.snp.makeConstraints({ $0.center.equalToSuperview() })
于 2013-11-08T09:10:14.237 に答える
10

絶対に可能だったのは、次のようにすることでした。

[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])
于 2015-01-31T22:14:25.977 に答える
8

以下のコードを追加して、ボタンを画面の中央に配置します。絶対に可能です。

[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]];
于 2016-09-13T13:08:41.313 に答える
1

あなたが望んでいないことはわかっていますが、もちろんマージンを計算し、それらを使用して視覚的なフォーマット文字列を作成できます;)

とにかく、いいえ。残念ながら、VFL でそれを「自動的に」行うことはできません - 少なくともまだです。

于 2012-10-29T09:12:55.510 に答える
0

追加のビューを使用できます。

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: 英語は私の第 2 言語なので、追加のビューを「プレースホルダー」と呼べるかどうかはわかりません。誰かが私にそれを教えてくれれば幸いです。

于 2015-03-21T13:58:08.937 に答える
0

やらなければならないことは、辞書でスーパービューを宣言することです。を使用する代わりに、 を使用し|ます@{@"super": view.superview};

NSLayoutFormatAlignAllCenterXオプションとして縦用と横NSLayoutFormatAlignAllCenterY用があります。

于 2014-11-12T11:58:01.063 に答える
0

ベースのソリューションを求めてここに来た人Interface Builder(Google が私をここに導いてくれます) は、const の幅/高さの制約を追加し、サブビューを選択するだけです -> そのスーパービューにドラッグを制御します -> 「スーパービューで垂直方向/水平方向に中央揃え」を選択します。

于 2015-05-12T06:54:24.497 に答える
-1

制約の代わりにこれを使用できると言う必要があります。

child.center = [parent convertPoint:parent.center fromView:parent.superview];
于 2016-02-25T06:50:58.877 に答える
-3

VFL を使用する代わりに、インターフェイス ビルダーで簡単にこれを行うことができます。メイン ストーリーボードで、中央に配置するビューを Ctrl キーを押しながらクリックします。(Ctrl キーを押しながら) スーパービューにドラッグし、"Center X" または "Center Y" を選択します。コードは必要ありません。

于 2014-09-10T14:49:23.940 に答える