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

Posted

技术标签:

【中文标题】以编程方式使用自动布局添加许多按钮以查看 X、Y、填充约束【英文标题】:Add a number of buttons to view with X,Y,padding constraints using autolayout programatically 【发布时间】:2013-10-25 08:17:49 【问题描述】:

假设我有 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-[按钮]50-| 顶部和底部带内边距 1 对于最顶部/底部的按钮,其填充将是动态的

如果我在 INTERFACE BUILDER 上执行它会是这样的......(因此我需要以编程方式执行)

【问题讨论】:

【参考方案1】:

我认为这是可行的,它在按钮周围设置了一个 wrapperView,在此视图内对齐按钮并将 wrapperView 居中于其父视图内。

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];

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

【讨论】:

以上是关于以编程方式使用自动布局添加许多按钮以查看 X、Y、填充约束的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式使用自动布局约束的问题

在情节提要中添加自动布局,然后以编程方式更新它

以编程方式在 xib 上使用自动布局创建的两个文本字段之间添加 uiview

以编程方式调整控件框架

以编程方式将自动布局约束添加到恒定宽度和高度的子视图

如何以编程方式使用自动布局以编程方式添加 UIview?