使用自动布局以编程方式添加多个按钮以查看X,Y,填充约束

时间:2013-10-25 08:17:50

标签: ios xcode button autolayout nslayoutconstraint

假设我有N个按钮..

//---listOfServicesToDisplay is DYNAMIC
NSMutableArray * arrayOfButtons = [NSMutableArray array];
for (int i=0; i<[listOfServicesToDisplay count]; i++) {
    UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [arrayOfButtons addObject:button];
}

我想将arrayOfButtons添加到我的superView中,约束为:

  • 中心Y对齐(垂直)
  • 中心X对齐(水平)
  • 50个填充的前导和尾随。 H:| 50-BUTTON] 50- |
  • 顶部和底部有填充1
  • 对于最顶部/底部按钮,其填充将是动态的

如果我在INTERFACE BUILDER上这样做它会是这样的......(因此我需要在程序上这样做)

enter image description here

1 个答案:

答案 0 :(得分:2)

我认为这很有效,它在按钮周围设置了一个包装器,在这个视图中对齐按钮,并将wrapperView置于其superview中。

UIView *buttonView = [UIView new];
[buttonView setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.view addSubview:buttonView];

NSLayoutConstraint *horizontal = [NSLayoutConstraint constraintWithItem:buttonView
                                                              attribute:NSLayoutAttributeCenterX
                                                              relatedBy:NSLayoutRelationEqual
                                                                 toItem:buttonView.superview
                                                              attribute:NSLayoutAttributeCenterX
                                                             multiplier:1.0
                                                               constant:0.0];

NSLayoutConstraint *vertical = [NSLayoutConstraint constraintWithItem:buttonView
                                                            attribute:NSLayoutAttributeCenterY
                                                            relatedBy:NSLayoutRelationEqual
                                                               toItem:buttonView.superview
                                                            attribute:NSLayoutAttributeCenterY
                                                           multiplier:1.0
                                                             constant:0];

NSLayoutConstraint *width = [NSLayoutConstraint constraintWithItem:buttonView
                                                         attribute:NSLayoutAttributeWidth
                                                         relatedBy:NSLayoutRelationEqual
                                                            toItem:buttonView.superview
                                                         attribute:NSLayoutAttributeWidth
                                                        multiplier:1.0
                                                          constant:-100];

// height will have to wait until we know what the buttons are up to

[buttonView.superview addConstraints:@[horizontal, vertical,width]];

CGFloat buttonHeight = 50;
CGFloat buttonSpace = 10;

NSInteger numberOfButtons = [buttons count]; // buttons = your array of buttons
for (NSInteger index = 0; index < numberOfButtons; index++) {
    UIButton *button = [buttons objectAtIndex:index];
    [buttonView addSubview:button];

    NSLayoutConstraint *width = [NSLayoutConstraint constraintWithItem:button
                                                             attribute:NSLayoutAttributeWidth
                                                             relatedBy:NSLayoutRelationEqual
                                                                toItem:buttonView
                                                             attribute:NSLayoutAttributeWidth
                                                            multiplier:1.0
                                                              constant:0];

    NSLayoutConstraint *height = [NSLayoutConstraint constraintWithItem:button
                                                              attribute:NSLayoutAttributeHeight
                                                              relatedBy:NSLayoutRelationEqual
                                                                 toItem:Nil
                                                              attribute:NSLayoutAttributeNotAnAttribute
                                                             multiplier:1.0
                                                               constant:buttonHeight];

    NSLayoutConstraint *horizontal = [NSLayoutConstraint constraintWithItem:button
                                                                  attribute:NSLayoutAttributeCenterX
                                                                  relatedBy:NSLayoutRelationEqual
                                                                     toItem:buttonView
                                                                  attribute:NSLayoutAttributeCenterX
                                                                 multiplier:1.0
                                                                   constant:0];

    [buttonView addConstraints:@[ width, height, horizontal]];

    // a bit clumsy here, due to the first button
    if (index == 0) {
        NSLayoutConstraint *vertical = [NSLayoutConstraint constraintWithItem:button
                                                                    attribute:NSLayoutAttributeTop
                                                                    relatedBy:NSLayoutRelationEqual
                                                                       toItem:button.superview
                                                                    attribute:NSLayoutAttributeTop
                                                                   multiplier:1.0
                                                                     constant:0];

        [button.superview addConstraint:vertical];
    } else{
        UIButton *formerButton = [buttons objectAtIndex:index-1];
        NSLayoutConstraint *vertical = [NSLayoutConstraint constraintWithItem:button
                                                                    attribute:NSLayoutAttributeTop
                                                                    relatedBy:NSLayoutRelationEqual
                                                                       toItem:formerButton
                                                                    attribute:NSLayoutAttributeBottom
                                                                   multiplier:1.0
                                                                     constant:buttonSpace];

        [button.superview addConstraint:vertical];
    }
}

UIButton *lastButton = [buttons lastObject];
CGFloat viewHeight = (buttonSpace + buttonHeight) * [buttons count];

NSLayoutConstraint *height = [NSLayoutConstraint constraintWithItem:buttonView
                                                              attribute:NSLayoutAttributeHeight
                                                              relatedBy:NSLayoutRelationEqual
                                                                 toItem:nil
                                                              attribute:NSLayoutAttributeNotAnAttribute
                                                             multiplier:1.0
                                                               constant:viewHeight];
[buttonView addConstraint:height];

现在,我根本没有尝试清理它,你当然不希望将这一切都集中在一块,但这个概念是合理的,你应该能够达到你想要的效果。就个人而言,我经常使用一个单独的类来处理约束,以避免重复代码。