自动布局让我的生活很困难。从理论上讲,当我转换的时候,它会非常有用,但我似乎一直在与它作斗争。

我做了一个演示项目来寻求帮助。有人知道如何使视图之间的空间增加或减少均匀,每当视图调整大小?

下面是三个标签(手动垂直对齐):

我想要的是,当我旋转时,它们均匀地调整间距(而不是视图大小)。默认情况下,顶部和底部视图向中心挤压:


当前回答

我可以在IB中完全解决这个问题:

使约束使每个子视图的中心Y对齐到父视图的下边缘。 将每个约束的乘数设置为1/2n, 3/2n, 5/2n,…,n-1/2n,其中n是要分布的子视图的数量。

因此,如果您有三个标签,请将每个约束的乘数设置为0.1666667、0.5、0.833333。

其他回答

我想水平对齐5张图片,所以我最终遵循了Mete的反应,但有一点不同。

第一个图像将在容器中水平居中,容器的值为0,乘数为1:5:

第二张图片将在容器中水平居中,容器的值为0,乘数为3:5:

其余的图像也是这样。例如,第五张(也是最后一张)图像将在容器中水平居中,容器值为0,乘数为9:5:

正如梅特所解释的,顺序是1,3,5,7,9,等等。位置遵循相同的逻辑:第一个位置是1,然后是空格,然后是下一个位置3,依此类推。

我知道距离第一个答案已经有一段时间了,但我刚刚遇到了同样的问题,我想分享我的解决方案。为了子孙后代……

我在viewDidLoad上设置了视图:

- (void)viewDidLoad {

    [super viewDidLoad];

    cancelButton = [UIButton buttonWithType: UIButtonTypeRoundedRect];
    cancelButton.translatesAutoresizingMaskIntoConstraints = NO;
    [cancelButton setTitle:@"Cancel" forState:UIControlStateNormal];
    [self.view addSubview:cancelButton];

    middleButton = [UIButton buttonWithType: UIButtonTypeRoundedRect];
    middleButton.translatesAutoresizingMaskIntoConstraints = NO;
    [middleButton setTitle:@"Middle" forState:UIControlStateNormal];
    [self.view addSubview:middleButton];

    nextButton = [UIButton buttonWithType: UIButtonTypeRoundedRect];
    nextButton.translatesAutoresizingMaskIntoConstraints = NO;
    [nextButton setTitle:@"Next" forState:UIControlStateNormal];
    [self.view addSubview:nextButton];


    [self.view setNeedsUpdateConstraints];

}

然后,在updateViewConstrains上,首先删除所有约束,然后创建视图字典,然后计算视图之间使用的空间。在那之后,我只是使用视觉语言格式设置约束:

- (void)updateViewConstraints {


    [super updateViewConstraints];

    [self.view removeConstraints:self.view.constraints];

    NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(cancelButton, nextButton, middleButton);

    float distance=(self.view.bounds.size.width-cancelButton.intrinsicContentSize.width-nextButton.intrinsicContentSize.width-middleButton.intrinsicContentSize.width-20-20)/  ([viewsDictionary count]-1);  // 2 times 20 counts for the left & rigth margins
    NSNumber *distancies=[NSNumber numberWithFloat:distance];

//    NSLog(@"Distancies: %@", distancies);
//    
//    NSLog(@"View Width: %f", self.view.bounds.size.width);
//    NSLog(@"Cancel Width: %f", cancelButton.intrinsicContentSize.width);
//    NSLog(@"Middle Width: %f", middleButton.intrinsicContentSize.width);
//    NSLog(@"Next Width: %f", nextButton.intrinsicContentSize.width);



    NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"|-[cancelButton]-dis-[middleButton]-dis-[nextButton]-|"
                                                                   options:NSLayoutFormatAlignAllBaseline
                                                                   metrics:@{@"dis":distancies}
                                                                     views:viewsDictionary];


    [self.view addConstraints:constraints];



    constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[nextButton]-|"
                                                          options:0
                                                          metrics:nil
                                                            views:viewsDictionary];
    [self.view addConstraints:constraints];



}

这种方法的好处是你只需要做很少的数学运算。我并不是说这是完美的解决方案,但我为我试图实现的布局工作。

我希望这能有所帮助。

我的方法允许你在接口构建器中做这个。你要做的是创建“间隔视图”,你已经设置为匹配高度相等。然后在标签上添加顶部和底部约束(见截图)。

更具体地说,我在“Spacer View 1”上有一个顶部约束,以优先级低于1000的高度约束来superview,并且高度等于所有其他的“Spacer views”。'Spacer View 4'有一个用于superview的底部空间约束。每个标签都有各自的顶部和底部约束到其最近的“间隔视图”。

注意:确保你的标签上没有额外的顶部/底部空间限制;只有那些“空间视图”。这是可以满足的,因为顶部和底部的约束分别在'Space View 1'和'Spacer View 4'上。

废话1:我复制了我的视图,只是把它设置为横向模式,这样你就可以看到它工作了。

废话2:“间隔视图”本可以是透明的。

废话3:这种方法可以横向应用。

我刚刚用乘数特性解决了我的问题。我不确定它是否适用于所有情况,但对我来说,它非常有效。我在Xcode 6.3供你参考。

我最后做的是:

1)首先将我的按钮放置在320px宽度的屏幕上,以我希望它在320px设备上的方式分布。

2)然后我在所有按钮的superview上添加了一个领先的空间约束。

3)然后我修改了前导空间的属性,使常量为0,乘数是x偏移量除以屏幕宽度(例如,我的第一个按钮距离左边缘8px,所以我将乘数设置为8/320)

4)那么这里重要的一步是将约束关系中的第二个Item更改为superview。尾随而不是superview.leading。这很关键,因为superview。在我的例子中,前导为0,后拖为320,所以8/320在320px设备上是8px,然后当父视图的宽度改变为640或其他什么时,视图都以相对于320px屏幕大小的宽度的比例移动。这里的数学比较容易理解。

Swift 3版本

let _redView = UIView()
        _redView.backgroundColor = UIColor.red
        _redView.translatesAutoresizingMaskIntoConstraints = false

        let _yellowView = UIView()
        _yellowView.backgroundColor = UIColor.yellow
        _yellowView.translatesAutoresizingMaskIntoConstraints = false

        let _blueView = UIView()
        _blueView.backgroundColor = UIColor.blue
        _blueView.translatesAutoresizingMaskIntoConstraints = false

        self.view.addSubview(_redView)
        self.view.addSubview(_yellowView)
        self.view.addSubview(_blueView)

        var views = ["_redView": _redView, "_yellowView": _yellowView, "_blueView":_blueView]

        var nslayoutConstraint_H = NSLayoutConstraint.constraints(withVisualFormat: "|->=0-[_redView(40)]->=0-[_yellowView(40)]->=0-[_blueView(40)]->=0-|", options: [.alignAllTop, .alignAllBottom], metrics: nil, views: views)
        self.view.addConstraints(nslayoutConstraint_H)

        var nslayoutConstraint_V = NSLayoutConstraint.constraints(withVisualFormat: "V:[_redView(60)]", options: NSLayoutFormatOptions.init(rawValue: 0), metrics: nil, views: views)
        self.view.addConstraints(nslayoutConstraint_V)


        let constraint_red = NSLayoutConstraint.init(item: self.view, attribute: .centerY, relatedBy: .equal, toItem: _redView, attribute: .centerY, multiplier: 1, constant: 0)
        self.view.addConstraint(constraint_red)

        let constraint_yellow = NSLayoutConstraint.init(item: self.view, attribute: .centerX, relatedBy: .equal, toItem: _yellowView, attribute: .centerX, multiplier: 1, constant: 0)
        self.view.addConstraint(constraint_yellow)

        let constraint_yellow1 = NSLayoutConstraint.init(item: _redView, attribute: .centerX, relatedBy: .equal, toItem: _yellowView, attribute: .leading, multiplier: 0.5, constant: 0)
        self.view.addConstraint(constraint_yellow1)

        let constraint_yellow2 = NSLayoutConstraint.init(item: _blueView, attribute: .centerX, relatedBy: .equal, toItem: _yellowView, attribute: .leading, multiplier: 1.5, constant: 40)
        self.view.addConstraint(constraint_yellow2)