iOS の AutoLayout の学習を始めたばかりで、Visual Format Language を調べました。
1 つのことを除いて、すべて正常に動作します。スーパービュー内でビューを中央に配置できません。
これは VFL で可能ですか、それともコンストレイントを自分で手動で作成する必要がありますか?
iOS の AutoLayout の学習を始めたばかりで、Visual Format Language を調べました。
1 つのことを除いて、すべて正常に動作します。スーパービュー内でビューを中央に配置できません。
これは VFL で可能ですか、それともコンストレイントを自分で手動で作成する必要がありますか?
現在、いいえ、 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 について多くのことを学びました。
はい、Visual Format Language を使用してビューをスーパービューの中央に配置することができます。縦にも横にも。デモは次のとおりです。
手動で制約を作成する方が良いと思います。
[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() })
絶対に可能だったのは、次のようにすることでした。
[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])
以下のコードを追加して、ボタンを画面の中央に配置します。絶対に可能です。
[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]];
あなたが望んでいないことはわかっていますが、もちろんマージンを計算し、それらを使用して視覚的なフォーマット文字列を作成できます;)
とにかく、いいえ。残念ながら、VFL でそれを「自動的に」行うことはできません - 少なくともまだです。
追加のビューを使用できます。
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 言語なので、追加のビューを「プレースホルダー」と呼べるかどうかはわかりません。誰かが私にそれを教えてくれれば幸いです。
やらなければならないことは、辞書でスーパービューを宣言することです。を使用する代わりに、 を使用し|
ます@{@"super": view.superview};
。
NSLayoutFormatAlignAllCenterX
オプションとして縦用と横NSLayoutFormatAlignAllCenterY
用があります。
ベースのソリューションを求めてここに来た人Interface Builder
(Google が私をここに導いてくれます) は、const の幅/高さの制約を追加し、サブビューを選択するだけです -> そのスーパービューにドラッグを制御します -> 「スーパービューで垂直方向/水平方向に中央揃え」を選択します。
制約の代わりにこれを使用できると言う必要があります。
child.center = [parent convertPoint:parent.center fromView:parent.superview];
VFL を使用する代わりに、インターフェイス ビルダーで簡単にこれを行うことができます。メイン ストーリーボードで、中央に配置するビューを Ctrl キーを押しながらクリックします。(Ctrl キーを押しながら) スーパービューにドラッグし、"Center X" または "Center Y" を選択します。コードは必要ありません。