我正在尝试在视图中水平对齐两到三个按钮。为简单起见,我将展示我对齐两个按钮的尝试。
这适用于标题较短的按钮:
@"H:|-10-[questionButton1(questionButton2)]-5-[questionButton2]-10-|"
但是只要其中一个按钮获得更长的标题,就会像这样打破:
我最终做的是计算每个按钮的宽度,然后如果button1宽度大于视图的一半并且大于button2宽度,我使用了:
@"H:|-10-[questionButton1(==btn1width)]-5-[questionButton2(>=btn2width)]-10-|"
它有点工作,但我不喜欢这种计算的代码外观。想象一下它增加了第三个按钮的复杂性。此外,如果两个按钮都具有相当长的标题,则会出现问题,在这种情况下,我必须弄清楚是否应该减小字体大小以使一切都合适。
我在这里发布这个是因为我可能会遗漏一些关于autolayout的神奇事情,因为我今天才开始在代码中使用它。任何形式的帮助将不胜感激。
---更新(澄清)---
我希望按钮分开考虑边距(外侧10个,按钮5个)。理想情况下,如果文本大小适合其默认大小,它们应该是相同的宽度(50%:两个按钮为50%,33%:33%:三个按钮为33%)。如果按钮标题超过完美宽度,如果其他按钮允许按钮(如果其他按钮可以缩小),按钮应该扩展其宽度。如果没有可能的扩展或缩小,则大按钮应减小字体大小并重复该过程(检查其他按钮是否可以缩小)。是的,我知道,我要求很多:)
---更新---
btn.contentEdgeInsets = UIEdgeInsetsMake(0, 5, 0, 5);
btn.titleLabel.adjustsFontSizeToFitWidth = YES;
btn.titleLabel.numberOfLines = 0;
btn.titleLabel.minimumScaleFactor = 0.7;
最终结果:
答案 0 :(得分: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]];
}
因此,如果内容可以放在这些标签内:
但如果其中一个长得更长:
内容压缩阻力优先级是一种告诉自动布局您希望组件保持多远的内在大小(因此名称压缩阻力)的方法。
这种方法也可以在IB中更容易实现。可以在尺寸检查器标签(cmd
+ opt
+ 5
)中设置内容抵抗优先级。
答案 1 :(得分:2)
如果您正在使用自动布局,则只需使用约束即可确保按钮始终垂直或水平对齐。为了使它们水平对齐(即将它们的y值对齐),只需通过按住命令并单独单击它们来选择两个按钮:
它们将出现在故事板中,并带有选择器指示器。现在转到右下角,选择对齐他们的"垂直中心"。对齐垂直中心将使它们水平对齐(根据您的图表)。
这可确保它们始终水平对齐。
要解决有关文本扩展的问题,我可以想到解决这个问题的方法是创建一个UIView然后将UILabel放入模拟按钮。您必须将视图链接到某个IBOutlet,以便在按下它时将其链接到您希望它执行的功能。但是UILabel具有您可以使用Attributes Inspector在此处显示的Storyboard中设置的属性:
如果您选择"最小字体大小",设置该值,那么您的文本将在填满分配的空间时自动缩小,如下所示:
答案 2 :(得分:0)
随着文本增长以填充其宽度,最终会出现约束歧义。不知道将会发生什么!您需要使用约束优先级和不等式(以及可能改变的压缩阻力)来解决此问题。
这是我在两个标签之间消除歧义的代码,这样一个人可以牺牲另一个标签来增长:
let p = self.lab2.contentCompressionResistancePriorityForAxis(.Horizontal)
self.lab1.setContentCompressionResistancePriority(p+1, forAxis: .Horizontal)
但我还需要使用不等式来设置最初的宽度和间距:
self.view.addConstraints(
NSLayoutConstraint.constraintsWithVisualFormat(
"H:[v1(>=20)]-(>=20)-[v2(>=20)]", options: nil, metrics: nil, views: d)
)