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ですか?

4

6 に答える 6

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 のスーパービューの最小高は 748pts です。myView の幅は 200pts で、そのスーパービューに対して標準スペースに等しい右側のパディングがあります。

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

2番目の質問に関して:

( myViewNSDictionaryOfVariableBindings(self.myView)のプロパティ設定がある場合) を使用し、それを VFL にself.myView入力して VFL テキストで使用すると、autolayout が VFL テキストを解析しようとすると、おそらく例外が発生します。これは、辞書キーのドット表記とシステムが使用しようとしていることに関係していますvalueForKeyPath:同様の質問と回答については、こちらを参照してください

于 2012-10-24T18:54:39.083 に答える
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)]];
于 2013-02-13T02:36:19.000 に答える
11

迅速なバージョン

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)
    // ...
}

方法 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

ノート

  • Anchor スタイルはNSLayoutConstraintStyle よりも推奨される方法ですが、iOS 9 からしか利用できないため、iOS 8 をサポートしている場合でもNSLayoutConstraintStyle を使用する必要があります。
  • プログラムによる制約の作成のドキュメントも参照してください。
  • ピン留め制約を追加する同様の例については、この回答を参照してください。
于 2016-04-01T04:49:03.567 に答える
5

why can't I use a property like self.myView instead of a local variable like myView?

try using:

NSDictionaryOfVariableBindings(_view)

instead of self.view

于 2013-03-06T22:23:00.277 に答える
5

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

于 2012-10-10T23:04:37.737 に答える