私は多くの人がすでにこれについて多くの質問をしていることを知っていますが、答えがあってもそれを機能させることはできません。
ストーリーボードの制約を扱うときは簡単ですが、コードでは苦労します。たとえば、右側に表示を維持し、画面の向きに応じて画面の高さを表示するようにします。これは私のコードです:
UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 748)];
myView.backgroundColor = [UIColor redColor];
[self.view addSubview:myView];
[self.view addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"V:|-[myView(>=748)]-|"
options:0 metrics:nil
views:NSDictionaryOfVariableBindings(myView)]];
いくつかの制約を満たしていません。何が悪いのかわかりません。また、なぜmyView
のようなローカル変数の代わりにself.myView
のようなプロパティを使用できないのですか?
コードで自動レイアウトを使用する場合、フレームを設定しても何も起こりません。したがって、上のビューで幅200を指定したという事実は、それに制約を設定するときに何の意味もありません。ビューの制約セットを明確にするためには、特定の状態のx位置、y位置、幅、高さの4つのものが必要です。
現在、上記のコードには2つしかありません(高さ、スーパービューに対する相対的な位置、およびy位置、スーパービューに対する相対的な位置)。これに加えて、ビューのスーパービューの制約の設定方法に応じて競合する可能性のある2つの必須制約があります。 スーパービューに、高さが748未満の値であることを指定する必要な制約がある場合、「満たされない制約」例外が発生します。
制約を設定する前にビューの幅を設定したという事実は何も意味しません。古いフレームも考慮せず、それらのビューに指定したすべての制約に基づいて新しいフレームを計算します。コードで自動レイアウトを扱う場合、通常はinitWithFrame:CGRectZero
または単にinit
を使用して新しいビューを作成します。
質問で口頭で説明したレイアウトに必要な制約セットを作成するには、完全に指定されたレイアウトを提供するために、幅とx位置を区切るためにいくつかの水平制約を追加する必要があります。
[self.view addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"V:|-[myView(>=748)]-|"
options:NSLayoutFormatDirectionLeadingToTrailing
metrics:nil
views:NSDictionaryOfVariableBindings(myView)]];
[self.view addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"H:[myView(==200)]-|"
options:NSLayoutFormatDirectionLeadingToTrailing
metrics:nil
views:NSDictionaryOfVariableBindings(myView)]];
このレイアウトを口頭で説明すると、垂直方向の制約から次のようになります。
myViewは、そのスーパービューの高さを標準スペースに等しい上下のパディングで埋めます。 myViewのスーパービューの最小の高さは748ptsです。 myViewの幅は200ptsで、スーパービューに対して標準のスペースに等しい右側のパディングがあります。
スーパービューの高さを制限せずにビューがスーパービュー全体の高さだけを満たすようにしたい場合は、視覚形式テキストの(>=748)
パラメーターを省略します。 (>=748)
パラメーターが高さを与えるために必要だと思われる場合-この場合、バー(|
)またはスペースのあるバー(|-
、-|
)構文を使用してスーパービューの端にビューを固定しないでください。ビューのy位置(シングルエッジでのビューの固定)、および高さを持つy位置(両方のエッジでのビューの固定)により、ビューの制約セットを満たします。
2番目の質問に関して:
NSDictionaryOfVariableBindings(self.myView)
を使用して(myViewのプロパティが設定されている場合)、VFLテキストにself.myView
を使用するためにそれをVFLにフィードすると、おそらくautolayoutがVFLテキストを解析しようとすると例外が発生します。辞書キーのドット表記と、valueForKeyPath:
を使用しようとするシステムに関係しています。 同様の質問と回答はこちらをご覧ください 。
こんにちは、私はこのページを多くの制約と「方法」に使用しています。必要なことに気付くまでに永遠にかかりました。
myView.translatesAutoresizingMaskIntoConstraints = NO;
この例を機能させるには。 Userxxx、Rob M.、特にここの説明とコードについてlarsacusに感謝します。非常に貴重です。
上記の例を実行するための完全なコードは次のとおりです。
UIView *myView = [[UIView alloc] init];
myView.backgroundColor = [UIColor redColor];
myView.translatesAutoresizingMaskIntoConstraints = NO; //This part hung me up
[self.view addSubview:myView];
//needed to make smaller for iPhone 4 dev here, so >=200 instead of 748
[self.view addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"V:|-[myView(>=200)]-|"
options:NSLayoutFormatDirectionLeadingToTrailing
metrics:nil
views:NSDictionaryOfVariableBindings(myView)]];
[self.view addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"H:[myView(==200)]-|"
options:NSLayoutFormatDirectionLeadingToTrailing
metrics:nil
views:NSDictionaryOfVariableBindings(myView)]];
Swift 3に更新
この例では、Interface Builderで行う場合と同じように、次の制約をプログラムで追加する2つの方法を示します。
幅と高さ
コンテナの中心
override func viewDidLoad() {
super.viewDidLoad()
// set up the view
let myView = UIView()
myView.backgroundColor = UIColor.blue
myView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(myView)
// Add constraints code here (choose one of the methods below)
// ...
}
// width and height
myView.widthAnchor.constraint(equalToConstant: 200).isActive = true
myView.heightAnchor.constraint(equalToConstant: 100).isActive = true
// center in container
myView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
myView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
// width and height
NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 200).isActive = true
NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 100).isActive = true
// center in container
NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.centerX, relatedBy: NSLayoutRelation.equal, toItem: view, attribute: NSLayoutAttribute.centerX, multiplier: 1, constant: 0).isActive = true
NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.centerY, relatedBy: NSLayoutRelation.equal, toItem: view, attribute: NSLayoutAttribute.centerY, multiplier: 1, constant: 0).isActive = true
NSLayoutConstraint
スタイルよりも望ましい方法ですが、iOS 9からのみ使用できるため、iOS 8をサポートしている場合は、NSLayoutConstraint
スタイルを引き続き使用する必要があります。プロパティに関する2番目の質問については、クラスでプロパティとして宣言した場合にのみself.myView
を使用できます。 myView
はローカル変数であるため、そのように使用することはできません。この詳細については、 宣言されたプロパティ のAppleドキュメントを参照することをお勧めします。
myViewのようなローカル変数の代わりにself.myView
のようなプロパティを使用できないのはなぜですか?
使用してみてください:
NSDictionaryOfVariableBindings(_view)
self.view
の代わりに
IOS9から、新しいヘルパークラス NSLayoutAnchor のサブクラスを使用して、制約をプログラムで「より簡潔で読みやすい」に定義できることに注意してください。
ドキュメントの例:
[self.cancelButton.leadingAnchor constraintEqualToAnchor:self.saveButton.trailingAnchor constant: 8.0].active = true;