Autolayout约束警告"将试图通过违反约束来恢复" (可能的逻辑问题)

时间:2014-08-03 18:26:21

标签: objective-c xcode5 autolayout ios7.1

当我在此设备上运行该应用时,我正在为iPhone 4设置一些细节限制。在对齐和一切方面,一切看起来都很棒。

但是,我正在试图通过打破约束来试图恢复它们。

这个方法在检测到它是否是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 )>

如果你们需要更多信息,请告诉我。

2 个答案:

答案 0 :(得分:19)

这三个限制因素:

"<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点宽。

这三个限制因素:

"<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也无法读懂。

通常,您不要在按钮上设置宽度约束;你让它使用它的内在大小和适当的内容拥抱和抗压性优先级。此外,您可能不希望在按钮的任一侧设置硬间距。要么让间距在没有约束的情况下变化,那么按钮可以是它的内在大小,降低该约束的优先级,因此它是可选的,或者使不等式成为最小间距但不是精确间距。

答案 1 :(得分:3)

您过多地限制了自己的观点。你必须总是留下例如leftmargin,width和rightmargin灵活的一个,并让autolayout引擎拉伸那个。

没有任何数字的单个短划线表示默认距离,即20像素。因此,如果您删除

上的尾随约束
@"H:|-78-[myNext(==173)]-|"
@"H:|-11.5-[myBtn(==54)]-|"

并将其更改为

@"H:|-78-[myNext(==173)]"
@"H:|-11.5-[myBtn(==54)]"
然后,布局引擎将拉伸按钮的右边距以使其适合 包含视图。当然还有其他方法可以放松这些约束,这些都取决于你的设计目标。

就个人而言,我从不使用标准API:s进行自动布局。我使用了库PureLayout,它精彩地抽象了autolayout!