使用自动布局 VFL 垂直堆叠一组按钮

Posted

技术标签:

【中文标题】使用自动布局 VFL 垂直堆叠一组按钮【英文标题】:Vertically stack an array of buttons using auto layout VFL 【发布时间】:2015-02-27 16:12:29 【问题描述】:

我正在学习自动布局,我想将一组按钮设置为垂直堆叠并均匀分布。我还希望将按钮固定在视图的底部。用 VFL 设置这些约束的好方法是什么?按钮列表将作为 UIButtons 数组传入。

NSArray *buttons = [button1, button2, button3, button4, ...]
NSMutableArray *allConstraints = [NSMutableArray array]
UIButton *previousButton;

for (UIButton button in buttons) 
    // Buttons take up full width 
    NSArray *constraints = [NSLayoutConstraint
            constraintsWithVisualFormat:@"H:|[button]|"
                                options:0
                                metrics:nil
                                  views:NSDictionaryOfVariableBindings(button);];
    [allConstraints addObjectsFromArray:constraints];

    constraints = [NSLayoutConstraint
            constraintsWithVisualFormat:@"V:|[button]|"
                                options:0
                                metrics:nil
                                  views:NSDictionaryOfVariableBindings(button);];
    [allConstraints addObjectsFromArray:constraints];

    if (!previousButton) 
        NSDictionary *metrics = @@"padding" : @(10);

        // Make buttons height
        constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[-(padding)-previousButton(==button)]"
                                                              options:0
                                                              metrics:metrics
                                                                views:NSDictionaryOfVariableBindings(previousButton, button)];
        [allConstraints addObjectsFromArray:constraints];
    
    previousButton = button;


[self.view addConstraints:allConstraints]

这并不能满足我的需要,因为按钮没有固定在视图的底部。

【问题讨论】:

【参考方案1】:

我会以不同的方式来做。我不会在循环中构建约束,而是在循环中构建格式字符串。

-(void)addButtonsWithConstraints:(NSArray *) buttons 
    NSMutableDictionary *views = [NSMutableDictionary new];
    for (int i = 0; i<buttons.count; i++) 
        [buttons[i] setTranslatesAutoresizingMaskIntoConstraints: NO];
        [self.view addSubview:buttons[i]];
        [views setObject:buttons[i] forKey:[NSString stringWithFormat:@"button%d",i]];
    

    NSMutableString *formatString = [@"V:" mutableCopy];
    for (int i = 0; i<buttons.count-1; i++) 
        [formatString appendFormat:@"[button%d]-10-", i];
    
    [formatString appendFormat:@"[button%lu]|", buttons.count - 1]; // pins the last button to the bottom of the view
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:formatString options:NSLayoutFormatAlignAllLeft | NSLayoutFormatAlignAllRight metrics:nil views:views]];
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[button0]|" options:0 metrics:nil views:views]];

最后一行将 button0 设置为视图的全宽,上一行中的格式选项使所有按钮的左右边缘对齐。

【讨论】:

记得检查数组是否为空!【参考方案2】:

你好,这可能对你有帮助

NSArray *buttons = @[button1, button2, button3, button4, button5];
NSMutableArray *allConstraints = [NSMutableArray array];
UIButton *previousButton;

for (UIButton *button in buttons) 
    [button setTranslatesAutoresizingMaskIntoConstraints:NO];
    // Buttons take up full width
    NSArray *constraints = [NSLayoutConstraint
                            constraintsWithVisualFormat:@"H:|[button]|"
                            options:0
                            metrics:nil
                            views:NSDictionaryOfVariableBindings(button)];
    [allConstraints addObjectsFromArray:constraints];
    if (!previousButton) 
    constraints = [NSLayoutConstraint
                   constraintsWithVisualFormat:@"V:|->=10-[button(65)]"
                   options: 0
                   metrics:nil
                   views:NSDictionaryOfVariableBindings(button)];
                [allConstraints addObjectsFromArray:constraints];
    
    if (previousButton) 
        NSDictionary *metrics = @@"padding" : @(10);

        // Make buttons height
        constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[previousButton]-(20)-[button(65)]"
                                                              options:0
                                                              metrics:metrics
                                                                views:NSDictionaryOfVariableBindings(previousButton, button)];
        [allConstraints addObjectsFromArray:constraints];
    
    previousButton = button;

NSArray *constraints = [NSLayoutConstraint
                        constraintsWithVisualFormat:@"V:[previousButton]-10-|"
                        options:0
                        metrics:nil
                        views:NSDictionaryOfVariableBindings(previousButton)];
[allConstraints addObjectsFromArray:constraints];
[self.view addConstraints:allConstraints]

【讨论】:

有了button(65),你是说按钮不能小于那个高度值吗?有没有办法自动配置它,而不用硬编码? 嗨@WillamHill,是的,按钮(65)我正在固定它的高度。如果您不想这样做,也可以这样做。如果您不指定高度,则带有文本的按钮将高度为 30,如果按钮是图像,它将根据需要调整自身大小

以上是关于使用自动布局 VFL 垂直堆叠一组按钮的主要内容,如果未能解决你的问题,请参考以下文章

iOS - 按钮的自动布局/大小类

使用Auto Layout中的VFL(Visual format language)--代码实现自动布局

使用Auto Layout中的VFL(Visual format language)--代码实现自动布局转

iOS,自动布局autoresizing和auto layout,VFL语言

如何在 iOS7 中使用自动布局让按钮垂直增长?

垂直布局组自动扩展