iOS: Simple AutoLayout with 1 Label and 3 Buttons

mbm*_*414 1 ios autolayout

I'm playing around with AutoLayout and am really banging my head against the wall for what seems like it ought to be an extremely simple solution.

  1. I've got a vertical column of controls: 1 label and 3 buttons.
  2. I want the label to be 40 pixels(points) tall and auto-size its width based on the width of its superview (standard spacing on left, top and right).
  3. I want the 3 buttons to line up vertically below that label.
  4. I would like their widths to auto-size just like the label.
  5. I would like their spacing to be standard (aqua?) spacing (8 points, right?).
  6. I would like the 3 buttons to be the same height.

I can get what I want to happen to work, but I keep getting errors in the console at runtime, and I'd like to figure out WHY I'm getting them and HOW to avoid getting them. I've watched the WWDC videos on AutoLayout, and here's what I've tried so far:

UILabel *label = [self Label];
MMGlossyButton *button1 = ...
MMGlossyButton *button2 = ...
MMGlossyButton *button3 = ...
[[self view] addConstraints:
    [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[label]-|"
    options:0
    metrics:nil
    views:NSDictionaryOfVariableBindings(label)]];
[[self view] addConstraints:
    [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[button1]-|"
    options:0
    metrics:nil
    views:NSDictionaryOfVariableBindings(new)]];
[[self view] addConstraints:
    [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[button2]-|"
    options:0
    metrics:nil
    views:NSDictionaryOfVariableBindings(existing)]];
[[self view] addConstraints:
    [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[button3]-|"
    options:0
    metrics:nil
    views:NSDictionaryOfVariableBindings(provider)]];
[[self view] addConstraints:
    [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[label(40)]-[button1(>=25)]-[button2(==button1)]-[button3(==button1)]-|"
    options:0
    metrics:nil
    views:NSDictionaryOfVariableBindings(label, button1, button2, button3)]];
Run Code Online (Sandbox Code Playgroud)

So, this works for displaying the view in a dynamically-sized way, but the following error pops up in the console:

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) 

// A whole bunch of constraint stuff that doesn't appear to be important...

Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x7554c40 V:[MMGlossyButton:0x7554b40(99)]>
Run Code Online (Sandbox Code Playgroud)

So, the last bit appears to indicate that the first button I have on the view is statically sized to 99 points tall.
Which is the size it has on the view.
Which is completely arbitrary.
Which I don't want assigned, but can't figure out a way to un-assign it.

虽然我得到了我想要的东西(最终是这样),但它似乎是一种非常简单的迂回方式来完成一些非常简单的事情.我错过了一些关于AutoLayout的基本知识,还是它的功能需要如此复杂?

jrt*_*ton 7

您遇到错误,因为您正在混合和匹配代码中生成的约束与接口构建器添加的约束.界面构建器不允许您生成模糊的布局,因此几乎按照定义,如果添加其他约束,您将收到"Unable to simultaneously satisfy"错误,这是许多婚姻的垮台.

要解决此问题,您需要在界面构建器中定义所需的所有约束,或者需要将特定的约束标记为出口并在添加自己的代码之前将其删除.

在您的情况下,约束很简单,可以在IB中创建.

在选择标签时,您可以使用IB中的此按钮固定到特定高度:

在此输入图像描述

中间的那个,看起来像一个大梁.这将为您提供以下有用的菜单:

在此输入图像描述

选择其中一个允许您为标签创建一个新约束,然后您可以通过选择它来编辑它:

在此输入图像描述

然后,您可以添加按钮,选择所有这三个按钮,然后使用相同的菜单创建相等的高度约束.

在IB中创建的约束不是特别灵活,因此如果您确定需要在代码中创建或修改它们,最好为特定约束创建出口,然后删除并重新创建它们,或者修改constant运行时的值.