私はAutoLayout for iOSの学習を始めたばかりで、Visual Format Languageを調べました。
1つを除いて、すべて正常に機能します。スーパービューの中心にビューを配置できません。
これはVFLで可能ですか、それとも手動で制約を手動で作成する必要がありますか?
私はAutoLayout for iOSの学習を始めたばかりで、Visual Format Languageを調べました。
1つを除いて、すべて正常に機能します。スーパービューの中心にビューを配置できません。
これはVFLで可能ですか、それとも手動で制約を手動で作成する必要がありますか?
回答:
現在、いいえ、VFL のみを使用してスーパービューのビューを中央に配置することはできないようです。ただし、単一のVFL文字列と単一の追加の制約(軸ごと)を使用することはそれほど難しくありません。
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について多くを学びました。
|
、処理するため有効[superview]
です。[superview]
autolayout を使用することにより、スーパービューオブジェクトがその配置メトリックに含まれます(githubリンクでの彼の回答の場合、そのNSLayoutFormatAlignAllCenterY
/ X
メトリック)。
はい、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
SnapKitを使用することをお勧めします。これは、iOSとmacOSの両方で自動レイアウトを容易にするDSLです。
view.snp.makeConstraints({ $0.center.equalToSuperview() })
Warning once only: Detected a case where constraints ambiguously suggest a height of zero for a tableview cell's content view. We're considering the collapse unintentional and using standard height instead.
絶対に可能はこのようにすることができました:
[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]];
@Evgeniiからの回答のおかげで、私は要旨で完全な例を作成します:
https://gist.github.com/yallenh/9fc2104b719742ae51384ed95dcaf626
VFL(非常に直感的ではありません)を使用するか、手動で制約を使用して、ビューを垂直方向に中央揃えにすることができます。ちなみに、私はcenterYと高さの両方をVFLで一緒に組み合わせることはできません:
"H:[subView]-(<=1)-[followIcon(==customHeight)]"
現在のソリューションでは、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:英語が私の第二言語であるため、追加のビューを「プレースホルダー」と呼べるかどうかわかりません。誰か教えていただければ幸いです。
Interface Builder
ベースのソリューションのためにここに来た人(Googleがここで私をリードします)には、constの幅/高さの制約を追加し、サブビューを選択し、>コントロールをそのスーパービューにドラッグします。
//create a 100*100 rect in the center of superView
var consts = NSLayoutConstraint.constraints(withVisualFormat: "H:|-space-[myView]-space-|", options: [], metrics:["space":view.bounds.width/2-50], views:["myView":myView])
consts += NSLayoutConstraint.constraints(withVisualFormat: "V:|-space-[myView]-space-|", options: [], metrics: ["space":view.bounds.height/2-50], views: ["myView":myView])
Swift 2での@ igor-muzykaの回答:
NSLayoutConstraint.constraintsWithVisualFormat("H:[view]-(<=1)-[subview]",
options: .AlignAllCenterY,
metrics: nil,
views: ["view":view, "subview":subview])
VFLを使用する代わりに、インターフェースビルダーでこれを簡単に行うことができます。メインストーリーボードで、中央揃えにするビューをCtrlキーを押しながらクリックします。スーパービューにドラッグし(Ctrlキーを押しながら)、[中央X]または[中央Y]を選択します。コードは必要ありません。