以编程方式使用自动布局在视图中水平对齐按钮

bud*_*ino 1 ios autolayout nslayoutconstraint

我试图在视图中水平对齐两到三个按钮.为简单起见,我将展示我对齐两个按钮的尝试.

这适用于标题较短的按钮:

@"H:|-10-[questionButton1(questionButton2)]-5-[questionButton2]-10-|"
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

但是只要其中一个按钮获得更长的标题,就会像这样打破: 在此输入图像描述

我最终做的是计算每个按钮的宽度,然后如果button1宽度大于视图的一半并且大于button2宽度,我使用了:

@"H:|-10-[questionButton1(==btn1width)]-5-[questionButton2(>=btn2width)]-10-|"
Run Code Online (Sandbox Code Playgroud)

它有点工作,但我不喜欢这种计算的代码外观.想象一下它增加了第三个按钮的复杂性.此外,如果两个按钮都具有相当长的标题,则存在一个问题,在这种情况下,我必须弄清楚是否应该减小字体大小以使一切都适合.

我在这里发布这个是因为我可能会遗漏一些关于autolayout的神奇之处,因为我今天才开始在代码中使用它.任何形式的帮助将不胜感激.

---更新(澄清)---

考虑到边距(外侧10个,按钮5个),我希望按钮均匀分割.理想情况下,如果文本大小适合其默认大小,它们应该是相同的宽度(50%:两个按钮为50%,33%:33%:三个按钮为33%).如果按钮标题超过完美宽度,如果其他按钮允许按钮(如果其他按钮可以缩小),按钮应该扩展其宽度.如果没有可能的扩展或缩小,则大按钮应减小字体大小并重复该过程(检查其他按钮是否可以缩小).是的,我知道,我要求很多:)

它的外观如何运作

---更新---

@Sikhapol的回答帮我解决了.我添加了一些东西来减少字体大小,添加填充并使按钮标题在文本不适合时分成多行:

btn.contentEdgeInsets = UIEdgeInsetsMake(0, 5, 0, 5);
btn.titleLabel.adjustsFontSizeToFitWidth = YES;
btn.titleLabel.numberOfLines = 0;
btn.titleLabel.minimumScaleFactor = 0.7;
Run Code Online (Sandbox Code Playgroud)

最终结果: 最终结果

yus*_*024 8

使用内容压缩阻力优先!

您可以告诉自动布局尽量保持两个标签的相等宽度.但是你告诉它,让其中一个变得更大以适应内部的内容更重要.

为此,请将等宽约束的优先级设置为低于标签(或按钮)的内容压缩阻抗优先级.

- (void)viewDidLoad {
    [super viewDidLoad];

    UILabel *label1 = [[UILabel alloc] init];
    label1.text = @"this seems";
    label1.backgroundColor = [UIColor orangeColor];
    label1.translatesAutoresizingMaskIntoConstraints = NO;

    UILabel *label2 = [[UILabel alloc] init];
    label2.text = @"completely fine";
    label2.backgroundColor = [UIColor orangeColor];
    label2.translatesAutoresizingMaskIntoConstraints = NO;

    [self.view addSubview:label1];
    [self.view addSubview:label2];

    NSDictionary *views = NSDictionaryOfVariableBindings(label1, label2);

    NSArray *horizontalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-10-[label1(label2)]-5-[label2]-10-|"
                                                                             options:NSLayoutFormatAlignAllCenterY
                                                                             metrics:nil
                                                                               views:views];

    // Find the equal width constraint and set priority to high (750)
    for (NSLayoutConstraint *constraint in horizontalConstraints) {
        if (constraint.firstAttribute == NSLayoutAttributeWidth) {
            constraint.priority = UILayoutPriorityDefaultHigh;
        }
    }

    [self.view addConstraints:horizontalConstraints];

    // Set content compression resistant to required (1000)
    [label1 setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
    [label2 setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];

    // The below code is here to add the vertical center constraints. You can ignore it.
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:label1
                                                          attribute:NSLayoutAttributeCenterY
                                                          relatedBy:NSLayoutRelationEqual
                                                             toItem:self.view
                                                          attribute:NSLayoutAttributeCenterY
                                                         multiplier:1
                                                           constant:0]];

    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:label2
                                                          attribute:NSLayoutAttributeCenterY
                                                          relatedBy:NSLayoutRelationEqual
                                                             toItem:self.view
                                                          attribute:NSLayoutAttributeCenterY
                                                         multiplier:1
                                                           constant:0]];
}
Run Code Online (Sandbox Code Playgroud)

因此,如果内容可以适合这些标签:

适合

但如果其中一个变长:

扩大

内容压缩阻力优先级是一种告诉自动布局您希望组件保持其内在大小(因此名称压缩阻力)的程度.

这种方法也可以在IB中更容易地实现.可以在" 大小检查器"选项卡(cmd+ opt+ 5)中设置内容阻力优先级.