web-dev-qa-db-ja.com

自動レイアウト制約の警告「制約を解除して回復を試みます」

このデバイスでアプリを実行するときに、iPhone4にいくつかの特定の制約を設定しています。配置とすべての点ですべてが素晴らしく見えます。

しかし、制約を解除して回復しようとしているすべての制約でエラーが発生します。

このメソッドは、iPhone 4かどうかを検出すると、viewDidLoadで呼び出されます。

- (void) addConstraints {

    // removing automatic system constraints
    [self.view removeConstraints:self.view.constraints];
    [self.view setTranslatesAutoresizingMaskIntoConstraints:NO];


    NSDictionary *views = NSDictionaryOfVariableBindings(appBackground, myCustomer, myItemDetails, myItemQuantity, myItemPrice, myNext, myBtn); // UIImageView, UITextField, UIButton

    for (UIView *view in [views allValues]) {
        view.translatesAutoresizingMaskIntoConstraints = NO;
    }

    NSDictionary *metrics = @{@"width": @210.0, @"height": @42.0, @"verticalSpacing": @34};

    NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[appBackground]|"
                                                                   options:0
                                                                   metrics:nil
                                                                     views:views];

    constraints = [constraints arrayByAddingObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[appBackground]|"
                                                                   options:0
                                                                   metrics:nil
                                                                     views:views]];

    constraints = [constraints arrayByAddingObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(85)-[myCustomer(==height)]-(verticalSpacing)-[myItemDetails(==height)]-(verticalSpacing)-[myItemQuantity(==height)]-(verticalSpacing)-[myItemPrice(==height)]-(18)-[myNext(==35)]-(71.5)-[myBtn(==50)]-(7.5)-|"
                                                                    options:0
                                                                    metrics:metrics
                                                                      views:views]];

    constraints = [constraints arrayByAddingObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-50-[myCustomer(==width)]-|"
                                                                                                     options:0
                                                                                                     metrics:metrics
                                                                                                       views:views]];

    constraints = [constraints arrayByAddingObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-50-[myItemDetails(==width)]-|"
                                                                                                     options:0
                                                                                                     metrics:metrics
                                                                                                       views:views]];

    constraints = [constraints arrayByAddingObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-50-[myItemQuantity(==width)]-|"
                                                                                                     options:0
                                                                                                     metrics:metrics
                                                                                                       views:views]];

    constraints = [constraints arrayByAddingObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-50-[myItemPrice(==width)]-|"
                                                                                                     options:0
                                                                                                     metrics:metrics
                                                                                                       views:views]];

    constraints = [constraints arrayByAddingObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-78-[myNext(==173)]-|"
                                                                                                     options:0
                                                                                                     metrics:metrics
                                                                                                       views:views]];

    constraints = [constraints arrayByAddingObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-11.5-[myBtn(==54)]-|"
                                                                                                     options:0
                                                                                                     metrics:metrics
                                                                                                       views:views]];

    [self.view addConstraints:constraints];

}

エラー!

Unable to simultaneously satisfy constraints.
    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:0xb8282f0 H:|-(50)-[UITextField:0xb823fc0]   (Names: '|':UIView:0xb82f360 )>",
    "<NSLayoutConstraint:0xb828320 H:[UITextField:0xb823fc0(210)]>",
    "<NSLayoutConstraint:0xb82be10 H:[UITextField:0xb823fc0]-(NSSpace(20))-|   (Names: '|':UIView:0xb82f360 )>",
    "<NSLayoutConstraint:0xb82d3d0 H:|-(78)-[UIButton:0xb82ad50]   (Names: '|':UIView:0xb82f360 )>",
    "<NSLayoutConstraint:0xb82d420 H:[UIButton:0xb82ad50(173)]>",
    "<NSLayoutConstraint:0xb82d450 H:[UIButton:0xb82ad50]-(NSSpace(20))-|   (Names: '|':UIView:0xb82f360 )>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0xb82d450 H:[UIButton:0xb82ad50]-(NSSpace(20))-|   (Names: '|':UIView:0xb82f360 )>

Break on objc_exception_throw to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
2014-08-03 14:03:29.239 iReceipt[2886:607] Unable to simultaneously satisfy constraints.
    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:0xb8282f0 H:|-(50)-[UITextField:0xb823fc0]   (Names: '|':UIView:0xb82f360 )>",
    "<NSLayoutConstraint:0xb828320 H:[UITextField:0xb823fc0(210)]>",
    "<NSLayoutConstraint:0xb82be10 H:[UITextField:0xb823fc0]-(NSSpace(20))-|   (Names: '|':UIView:0xb82f360 )>",
    "<NSLayoutConstraint:0xb82d480 H:|-(11.5)-[UIButton:0xb820120]   (Names: '|':UIView:0xb82f360 )>",
    "<NSLayoutConstraint:0xb82e390 H:[UIButton:0xb820120(54)]>",
    "<NSLayoutConstraint:0xb82e3c0 H:[UIButton:0xb820120]-(NSSpace(20))-|   (Names: '|':UIView:0xb82f360 )>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0xb82e3c0 H:[UIButton:0xb820120]-(NSSpace(20))-|   (Names: '|':UIView:0xb82f360 )>

さらに情報が必要な場合はお知らせください。

8
valbu17

これらの3つの制約:

"<NSLayoutConstraint:0xb8282f0 H:|-(50)-[UITextField:0xb823fc0]   (Names: '|':UIView:0xb82f360 )>",
"<NSLayoutConstraint:0xb828320 H:[UITextField:0xb823fc0(210)]>",
"<NSLayoutConstraint:0xb82be10 H:[UITextField:0xb823fc0]-(NSSpace(20))-|   (Names: '|':UIView:0xb82f360 )>",

スーパービューの幅を50+ 210 + 20 == 280ポイントにするように指示します。

これらの3つの制約:

"<NSLayoutConstraint:0xb82d3d0 H:|-(78)-[UIButton:0xb82ad50]   (Names: '|':UIView:0xb82f360 )>",
"<NSLayoutConstraint:0xb82d420 H:[UIButton:0xb82ad50(173)]>",
"<NSLayoutConstraint:0xb82d450 H:[UIButton:0xb82ad50]-(NSSpace(20))-|   (Names: '|':UIView:0xb82f360 )>"

同じスーパービューが78+ 173 + 20 == 271ポイント幅であることを指示します。

明らかに、これらの両方を同時に真にすることはできません。ここで本当に何をしたいのかを決める必要があります。私たちはあなたの心を読むことができず、UIKitも読むことができません。

通常、ボタンに幅の制約を設定しません。コンテンツのハグと圧縮抵抗に適切な優先順位を付けて、固有のサイズを使用するようにします。また、ボタンの両側にハードスペースを設定したくない場合もあります。その間隔を制約なしで変化させてボタンをその固有のサイズにするか、その制約の優先度を下げてオプションにするか、不等式にして最小間隔を設定しますが、正確な間隔は設定しないでください。

18
Ken Thomases

ビューを制限しすぎています。たとえば、leftmargin、width、rightmarginのいずれかを常に柔軟なままにして、自動レイアウトエンジンにその1つを引き伸ばす必要があります。

数字のないダッシュは、デフォルトの距離である20ピクセルを意味します。したがって、末尾の制約を削除すると、

@"H:|-78-[myNext(==173)]-|"
@"H:|-11.5-[myBtn(==54)]-|"

それらをに変更します

@"H:|-78-[myNext(==173)]"
@"H:|-11.5-[myBtn(==54)]"

次に、レイアウトエンジンは、ボタンの右マージンを引き伸ばして、含まれているビューに合わせます。もちろん、これらの制約を緩和する方法は他にもありますが、すべて設計目標によって異なります。

個人的には、自動レイアウトに標準のAPIを使用することはもうありません。私はライブラリを使用しています PureLayout これは自動レイアウトを素晴らしく抽象化します!

3
Hunkpapa