1. ホーム
  2. objective-c

[解決済み] プログラムによるレイアウト制約の作成

2023-06-16 10:51:27

質問

この件に関して、すでに多くの人が大量の質問をしているのは知っていますが、その回答を見てもうまくいきません。

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

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 ?

どのように解決するのですか?

コードでオートレイアウトを使用する場合、フレームを設定しても何も起こりません。 したがって、上記のビューで 200 の幅を指定したという事実は、それに制約を設定するときには何の意味も持ちません。 ビューの制約セットがあいまいでないようにするためには、4 つのものが必要です。

現在、上記のコードでは、2 つしかありません (スーパー ビューに相対的な高さ、およびスーパー ビューに相対的な y-位置)。これに加えて、ビューのスーパービューの制約がどのように設定されるかによって衝突する可能性のある2つの必須の制約があります。 もし が、その高さが748より小さい値であることを指定する必須の制約を持っていた場合、"unsatisfiable constraints"例外が発生します。

制約を設定する前にビューの幅を設定したという事実は、何の意味もありません。 古いフレームを考慮することもなく、それらのビューに指定したすべての制約に基づいて新しいフレームを計算します。コードでオートレイアウトを扱う場合、私は通常、新しいビューを 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の幅は200ptsで、そのスーパービューに対して標準スペースと同じ右パディングを持ちます。 標準のスペースと同じです。

もし、スーパービューの高さを制限することなく、単にビューがスーパービューの高さ全体を埋めるようにしたい場合、単に (>=748) パラメータを省略します。もし (>=748) パラメータが高さを与えるために必要であると考えるなら - この例ではそうではありません: バー ( | ) またはスペース付きのバー ( |- , -| ) 構文を使用すると、ビューに y 位置 (ビューを 1 つのエッジに固定) と高さを持つ y 位置 (ビューを両方のエッジに固定) を与え、ビューの制約セットを満たしていることになります。

2番目の質問に関して。

使用方法 NSDictionaryOfVariableBindings(self.myView) (myViewにプロパティを設定していた場合)そしてそれをVFLに送り込んで self.myView を使用している場合、autolayout が VFL テキストをパースしようとすると例外が発生します。これは、辞書のキーがドット表記であることと、システムが valueForKeyPath: . 同様の質問と回答はこちらをご覧ください .