視覚フォーマット言語を使用してビューを中央に配置しようとしています。
_[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[_progressView(300)]-|" options:NSLayoutFormatAlignAllCenterY metrics:0 views:views]];
_
(views
は__progressView
_を含むNSDictionaryOfVariableBindings
です)
ビュー(幅:300)を_self.view
_(幅:768)の中央に配置しません。 @"H:|-[_progressView(300)"
とだけ書いたかのように、8ピクセルのマージンで左揃えにします。
次のようなものを使用してビューを中央に配置する唯一の方法はありますか?
_[self.view addConstraint:[NSLayoutConstraint constraintWithItem:_progressView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual
toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1 constant:0]];
_
ありがとう
このフォーマット文字列
@"H:|-[_progressView(300)]-|"
autoLayoutに中央揃えprogressView
を指示しません。代わりに、progressView
は300の幅であり、システムで定義された標準のマージンがスーパービューの端の両側にある必要があると述べています。明らかにこれは満足できないので、自動レイアウトはいくつかの制約を落とします(おそらくコンソールにいくつかのログが表示されます)。あなたのケースで削除された制約は、おそらく右側のマージンです。
ビューをスーパービューの真ん中に配置するには、既に理解しているように、視覚的な文字列形式の代わりに詳細な制約メソッドを使用する必要があります。ただし、次のように簡単にニースのカテゴリに入れることができます。
@interface UIView (MyLayout)
- (void)centerHorizontallyInSuperview;
@end
@implementation UIView (MyLayout)
- (void)centerHorizontallyInSuperview {
NSLayoutConstraint *c;
c = [NSLayoutConstraint constraintWithItem:self
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.superview
attribute:NSLayoutAttributeCenterX
multiplier:1
constant:0];
[self.superview addConstraint:c];
}
@end
3つのアプローチ:
DrummerBで提案されているように、メソッドまたはカテゴリに制約を追加するコードを配置できます。
また、効果的なiOS 9では、アンカーを使用し、activateConstraints
を使用して、より新しく、より簡潔な構文を使用できます。
[NSLayoutConstraint activateConstraints:@[
[centerView.centerXAnchor constraintEqualToAnchor:view.centerXAnchor],
...
]];
またはSwift 3:
NSLayoutConstraint.activate([
centerView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
...
])
UILayoutGuide
オブジェクトを使用できます。
UILayoutGuide *leftGuide = [[UILayoutGuide alloc] init];
[view addLayoutGuide:leftGuide];
UILayoutGuide *rightGuide = [[UILayoutGuide alloc] init];
[view addLayoutGuide:rightGuide];
次のように、VFLでそれらが互いに等しくなるように定義します。
H:|[leftGuide][_progressView(==300)][rightGuide(==leftGuide)]|
レイアウトガイドを使用できない場合(たとえば、9.0より前のiOSバージョンをサポートする必要がある場合、これをIBで作成する場合など)、非表示のUIView
オブジェクト(ゼロまたは背景のアルファ)を使用できます。クリアの色)と非常によく似ています。これらの「スペーサー」ビューをビュー階層に追加し、上記のような水平方向の制約を使用しますが、ビューが見えないように構成するだけです。
この手法は、「ビューを中央に配置する方法」の問題を解決する面倒な方法ですが、たとえば、12のビューを均等に配置したい場合にUIStackView
を使用できない場合に非常に役立ちます。何らかの理由で。希望する効果を実現するために、いくつでもUILayoutGuide
(または非表示のUIView
)オブジェクトを使用できます。
完全を期すために、私は https:/で概説されているように、options
/NSLayoutFormatAlignAllCenterX
のY
を使用して効果を達成することが可能であることを指摘する必要があります/stackoverflow.com/a/14917695/1271826 ですが、不必要に混乱していることを認めます。
個人的には、最初のアプローチがあなたのシナリオにとって最も理にかなっていると思います。 2番目の方法は、多数のコントロールを均等に配置しようとする場合に便利ですが、この単純なシナリオには扱いにくいです。 3番目のアプローチは知的好奇心ですが、実際のアプリケーションでは推奨しません。
それを必要とする人のために、@ DrummerBのObjCカテゴリはSwift拡張として:
extension UIView {
func centerInSuperview() {
self.centerHorizontallyInSuperview()
self.centerVerticallyInSuperview()
}
func centerHorizontallyInSuperview(){
let c: NSLayoutConstraint = NSLayoutConstraint(item: self, attribute: .CenterX, relatedBy: .Equal, toItem: self.superview, attribute: .CenterX, multiplier: 1, constant: 0)
self.superview?.addConstraint(c)
}
func centerVerticallyInSuperview(){
let c: NSLayoutConstraint = NSLayoutConstraint(item: self, attribute: .CenterY, relatedBy: .Equal, toItem: self.superview, attribute: .CenterY, multiplier: 1, constant: 0)
self.superview?.addConstraint(c)
}
}