プログラムによるレイアウト制約の作成


84

多くの人がすでにこれについてたくさんの質問をしていることを私は知っています、しかし答えがあっても私はそれを機能させることができません。

ストーリーボードの制約を扱うときは簡単ですが、コードでは苦労します。たとえば、右側にとどまり、画面の向きに応じた画面の高さを持つビューを作成しようとしています。これは私のコードです:

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

いくつかの制約を満たしていません。何が悪いのかわかりません。また、のようなself.myViewローカル変数の代わりにのようなプロパティを使用できないのはなぜmyViewですか?


上記のコードのviviとは何ですか?
iDev 2012年

14
タイトルを「IOS」ではなく「iOS」に変更してください。後者は、Ciscoのスイッチ/ルーターオペレーティングシステムを指します。私をまごつかせた。ありがとう。
アルマーニ2012年

1
これに関するいくつかの質問:(1)「いくつかの制約を満たさない」場合にどのようなエラーが発生しますか?(2)自動サイズ変更を制約に変換していmyViewますか?(3)vivi(ACBが尋ねたように)何ですか?(4)プロパティがmyView宣言されていselfますか?
ティム

1
ティム、ビビごめんなさい、タップが速すぎました...それはmyViewです。翻訳とはどういう意味ですか?私がすることはすべて上記のコードにあります。プロパティについて、プロパティとして宣言されている他のビューがいくつかありますが、それらのプロパティに同じコードを実装するとクラッシュします...メッセージ「エラー」は本当に大きいので、ここに貼り付けることはできません
pierre23

特定のビューから一時的に制約を削除するには、次のようにしますstackoverflow.com/questions/13388104/…–
Sam B

回答:


106

コードで自動レイアウトを使用する場合、フレームを設定しても何も起こりません。したがって、上のビューで幅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のスーパービューの最小の高さは748ポイントです。myViewの幅は200ポイントで、スーパービューに対する標準スペースに等しい右側のパディングがあります。

スーパービューの高さを制限せずに、ビューがスーパービューの高さ全体を埋めるだけの場合(>=748)は、ビジュアル形式のテキストのパラメーターを省略します。(>=748)高さを指定するためにパラメーターが必要であると思われる場合-この例ではそうではありません:バー(|)またはスペースのあるバー(|--|)構文を使用してビューをスーパービューのエッジに固定すると、ビューにyが与えられます。 -位置(単一のエッジでビューを固定)、および高さのあるy位置(両方のエッジでビューを固定)。これにより、ビューに設定された制約が満たされます。

2番目の質問に関して:

使用してNSDictionaryOfVariableBindings(self.myView)(あなたがMYVIEWのプロパティ設定を持っていた場合)、あなたのVFLに使用することを送りself.myView、あなたのVFLのテキストでは、おそらく自動レイアウトしようとは、あなたのVFLのテキストを解析するために例外が発生します。これは、辞書キーのドット表記と、使用しようとしているシステムと関係がありますvalueForKeyPath:同様の質問と回答については、こちらをご覧ください


UILabelのようないくつかのオブジェクトには固有のサイズがあり、そのオブジェクトの幅や高さを設定する必要はなく、位置だけを設定することを忘れないでください。ただし、高さまたは幅を設定すると、両方が削除されると思います。そのため、両方を指定する必要があります。
ニックターナー

この答えは私の質問に答えませんでしたが、それは私が何かを実現するのに役立ちました。してくれてありがとう!:)
Matej 2015年

1
これまでのところ、インターネット上で唯一の簡潔で読みやすい自動レイアウトの紹介。
ジョーイカーソン

plzは私を助けて、私の質問は...私はプログラム的制約を使用する方法を知らないこのです stackoverflow.com/questions/36326288/...

61

こんにちは私はこのページを制約と「ハウツー」のためにたくさん使っています。私が必要だと気付くまで、私は永遠にかかりました。

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

11

Swiftバージョン

Swift3用に更新

この例では、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)
    // ...
}

方法1:アンカースタイル

// 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

方法2:NSLayoutConstraintスタイル

// 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

ノート

  • アンカースタイルはNSLayoutConstraintStyleよりも推奨される方法ですが、iOS 9からのみ使用できるため、iOS 8をサポートしている場合は、引き続きNSLayoutConstraintStyleを使用する必要があります。
  • プログラムによる制約の作成に関するドキュメントも参照してください。
  • 固定制約を追加する同様の例については、この回答を参照してください。

5

プロパティに関する2番目の質問についてself.myViewは、クラスでプロパティとして宣言した場合にのみ使用できます。myViewはローカル変数なので、そのように使用することはできません。これについての詳細は、宣言されたプロパティに関するアップルのドキュメントを参照することをお勧めします


5

なぜ私はのようなプロパティを使用できないのですか self.myViewmyViewのようなローカル変数の代わりにのですか?

使用してみてください:

NSDictionaryOfVariableBindings(_view)

の代わりに self.view


それが私のアプリをクラッシュさせ、それはメッセージを与えます: '制約フォーマットを解析できません:polylineImageViewはビュー辞書のキーではありません。'
Tai Le

4

iOS9から、新しいヘルパークラスNSLayoutAnchorのサブクラスを使用して、プログラムで「より簡潔で読みやすい」制約を定義できることにも注意してください。

ドキュメントからの例:

[self.cancelButton.leadingAnchor constraintEqualToAnchor:self.saveButton.trailingAnchor constant: 8.0].active = true;
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.