web-dev-qa-db-ja.com

AutoLayout、制約を同時に満たすことができません

IOS AutoLayout、Interface Builderを非常に簡単に学び始めましたが、コード上で同じことをアーカイブしようとすると

    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(==2)-[_nextKeyboardButton]-(==2)-[_numPadButton]-(==2)-[_spaceButton]-(==2)-[_returnButton]-(==2)-|" options:0 metrics:0 views:NSDictionaryOfVariableBindings(_nextKeyboardButton,_numPadButton,_spaceButton,_returnButton)]];

例外が発生します

制約を同時に満たすことができません。

Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
(
 "<NSLayoutConstraint:0x6000000966c0 H:|-(2)-[UIButton:0x7fe4f1d1c760'Next']   (Names: '|':UIInputView:0x7fe4f1f04d00 )>",
 "<NSLayoutConstraint:0x600000096710 H:[UIButton:0x7fe4f1d1c760'Next']-(2)-[UIButton:0x7fe4f1d1d1d0'123']>",
 "<NSLayoutConstraint:0x600000096760 H:[UIButton:0x7fe4f1d1d1d0'123']-(2)-[UIButton:0x7fe4f1d1d6f0'Space']>",
 "<NSLayoutConstraint:0x6000000967b0 H:[UIButton:0x7fe4f1d1d6f0'Space']-(2)-[UIButton:0x7fe4f1d1d8d0'Return']>",
 "<NSLayoutConstraint:0x600000096800 H:[UIButton:0x7fe4f1d1d8d0'Return']-(2)-|   (Names: '|':UIInputView:0x7fe4f1f04d00 )>",
 "<NSLayoutConstraint:0x600000096e40 'UIView-Encapsulated-Layout-Width' H:[UIInputView:0x7fe4f1f04d00(0)]>"
 )

Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x6000000967b0 H:[UIButton:0x7fe4f1d1d6f0'Space']-(2)-[UIButton:0x7fe4f1d1d8d0'Return']>

4つのボタンすべて.translatesAutoresizingMaskIntoConstraints = NO;

何が間違っているのだろうか?ヘルプは本当にありがたいです:)

参考までに、私はiOS8 SDKに取り組んでいます

30

満たされない制約を見つける最も簡単な方法:

  • ビューのすべての制約に一意の識別子を設定します。

enter image description here

  • NSLayoutConstraintの単純な拡張を作成します。

Swift

extension NSLayoutConstraint {

    override public var description: String {
        let id = identifier ?? ""
        return "id: \(id), constant: \(constant)" //you may print whatever you want here
    }
}

OBJECTIVE-C

@interface NSLayoutConstraint (Description)

@end

@implementation NSLayoutConstraint (Description)

-(NSString *)description {
    return [NSString stringWithFormat:@"id: %@, constant: %f", self.identifier, self.constant];
}

@end
  • もう一度ビルドすると、より読みやすい出力が得られます。

enter image description here

  • idを取得したら、Find Navigatorで簡単にタップできます。

enter image description here

  • すぐに見つける:

enter image description here

その場合の簡単な修正方法は?

  • priority999壊れた制約。

関連する回答を参照してください: 制約を同時に満たすことができず、制約を破ることで回復を試みます

ストーリーボードに基づくビューコントローラーですべての自動レイアウト制約(Swiftで、Snappy-Swiftへの石積みポートを使用)を手動で作成しようとしたときに、同様の問題に苦労しなければなりませんでした。

何らかの理由で、Xcodeはビルド時にNIB上に自動レイアウト制約の独自のデフォルトセットを生成します。自動的に追加された制約と競合するため、これ以上手動制約を追加できなかったのはこのためです。

これを次の方法で解決しました。

  • 処理しているStoryboard View Controllerを開きます。

  • ビューコントローラーを選択し、メニューからエディター>自動レイアウトの問題を解決> []ビューコントローラーのすべてのビュー>不足している制約の追加を選択します。

enter image description here

(これにより、追加のビルド時間制約が作成されず、すべての制約が表示されるようになります。)

  • View Controllerからすべての制約を選択します。

enter image description here

  • 右側のペインから次のチェックボックスをチェックします。プレースホルダー-ビルド時に削除

enter image description here

これで、すべての自動レイアウト制約をコードに手動で追加できます。

8

他の誰かがこれに遭遇した場合、制約の問題を視覚的に確認する簡単な方法はこのサイトです(本当に便利です!):

http://www.wtfautolayout.com

以下は、サイトがダウンした場合のGithubプロジェクトです。 https://github.com/johnpatrickmorgan/wtfautolayout

3
JoniVR

メッセージコンソールの出力には、UIButtonの制約が再定義されていることが示されています。ボタンのHeightWidthを制限する制約を置くのと同じ意味ですが、不必要にボタンにAspect Ratio。この状態では、Xcodeはどの制約に従うかを確認できないため、このデバッグメッセージをコンソールで表示できます。

私に役立つ2つの方法があります。

  1. コンソールに表示された制約を分析し、1つ以上の制約を削除してください。

2. storyboardまたはXibを使用している場合、制約を選択->属性インスペクターを表示->いくつかの制約の優先度を変更します。


もう一つ...

Jason Jarrettの 記事 をたどることができます。シンボルブレークポイントを追加して、どのビューでエラーが発生するかを確認します。

3
lynulzy

あなたの質問によれば、あなたがnibでコントロールを作成し、あなたが直接変更しようとしていることはあなたのクラスからの制約です。

ここでできることは、View Controllerのnibに制約を設定し、それをクラスにバインドして、制約のオブジェクトを使用することです。または、プログラムでビューを作成し、制約を直接設定できます。

//また、「YES-ビューのスーパービューがビューの自動サイズ変更マスクを確認し、それを実装する制約を生成し、それらの制約を自身(スーパービュー)に追加する」場合、「translatesAutoresizingMaskIntoConstraints」が必要かどうかも確認する必要があります。 NO-ビューのスーパービューは、ビューの自動サイズ変更マスクを確認せず、それを実装する制約を生成しません。

私も同じ問題を抱えていて、次のように修正しました

     [_nextKeyboardButton setTranslatesAutoresizingMaskIntoConstraints:YES];
    _numPadButton.translatesAutoresizingMaskIntoConstraints = YES;
    [_numPadButton updateConstraints];
    [_nextKeyboardButton updateConstraints];

    NSArray *constraints2 = [NSLayoutConstraint
                             constraintsWithVisualFormat:@"H:|-57-[_nextKeyboardButton(96)]"
                             options:0
                             metrics:nil
                             views:NSDictionaryOfVariableBindings(_nextKeyboardButton)];

    [self.view addConstraints:constraints2];

    NSArray *constraints4 = [NSLayoutConstraint
                             constraintsWithVisualFormat:@"V:|-123-[_nextKeyboardButton(30)]"
                             options:0
                             metrics:nil
                             views:NSDictionaryOfVariableBindings(_nextKeyboardButton)];

    [self.view addConstraints:constraints4];

    NSArray *constraints1 = [NSLayoutConstraint
                             constraintsWithVisualFormat:@"H:|-207-[_numPadButton(58)]"
                             options:0
                             metrics:nil
                             views:NSDictionaryOfVariableBindings(_numPadButton)];

    [self.view addConstraints:constraints1];

    NSArray *constraints3 = [NSLayoutConstraint
                             constraintsWithVisualFormat:@"V:|-123-[_numPadButton(30)]"
                             options:0
                             metrics:nil
                             views:NSDictionaryOfVariableBindings(_numPadButton)];

    [self.view addConstraints:constraints3];

// Create Controls  or view programmatically.

UILabel *label = [UILabel new];
    label.text = @"This is a Label";
    label.font = [UIFont systemFontOfSize:18];
    label.backgroundColor = [UIColor lightGrayColor];
    label.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addSubview:label];

    NSArray *constraints = [NSLayoutConstraint
                            constraintsWithVisualFormat:@"V:|-offsetTop-[label(100)]"
                            options:0
                            metrics:@{@"offsetTop": @100}
                            views:NSDictionaryOfVariableBindings(label)];
    [self.view addConstraints:constraints];

    UIView *spacer1 = [UIView new];
    spacer1.translatesAutoresizingMaskIntoConstraints = NO;
    [spacer1 setBackgroundColor:[UIColor redColor]];
    [self.view addSubview:spacer1];

    UIView *spacer2 = [UIView new];
    spacer2.translatesAutoresizingMaskIntoConstraints = NO;
    [spacer2 setBackgroundColor:[UIColor greenColor]];
    [self.view addSubview:spacer2];

    NSArray *constraints1 = [NSLayoutConstraint
                            constraintsWithVisualFormat:@"V:|-offsetTop-[spacer1(100)]"
                            options:0
                            metrics:@{@"offsetTop": @100}
                            views:NSDictionaryOfVariableBindings(spacer1)];

    [self.view addConstraints:constraints1];

    NSArray *constraints2 = [NSLayoutConstraint
                             constraintsWithVisualFormat:@"V:|-offsetTop-[spacer2(100)]"
                             options:0
                             metrics:@{@"offsetTop": @100}
                             views:NSDictionaryOfVariableBindings(spacer2)];

    [self.view addConstraints:constraints2];

    [self.view addConstraints:[NSLayoutConstraint
                               constraintsWithVisualFormat:@"H:|[spacer1]-10-[label]-20-[spacer2(==spacer1)]|"
                               options:0
                               metrics:nil
                               views:NSDictionaryOfVariableBindings(label, spacer1, spacer2)]];

したがって、AutoLayoutを使用するときは、ビューのフレームを直接設定しないでください。これを行うために制約が使用されます。通常、ビューに独自の制約を設定する場合は、UIViewsのupdateConstraintsメソッドをオーバーライドする必要があります。ページコントローラのコンテンツビューは、ページビューのフレームに合わせてサイズ変更されるため、エッジのサイズを変更できることを確認してください。制約とビューのセットアップでは、これを考慮する必要があります。そうしないと、満足できない制約エラーが発生します。

https://developer.Apple.com/library/mac/documentation/userexperience/conceptual/AutolayoutPG/AutoLayoutConcepts/AutoLayoutConcepts.html#//Apple_ref/doc/uid/TP40010853-CH14-SW1 上記のAppleの詳細な研究へのリンクも参照してください。まだ問題に直面している場合は、問題を解決するために最善を尽くします。

2
user821127