如何以编程方式使用自动布局排列这三个 UILabel?

Posted

技术标签:

【中文标题】如何以编程方式使用自动布局排列这三个 UILabel?【英文标题】:How can I arrange these three UILabels using auto layout programmatically? 【发布时间】:2013-10-29 15:59:40 【问题描述】:

我有一个UIView,上面有三个UILabels。我有 titlesubtitlesubtitleDescription,所有 UILabel 属性。我希望我的标题在左上角,标题下方的字幕没有间隙,并且 subtitleDescription 到字幕的右侧没有间隙,将基线与字幕基线对齐。如果是视图,我想要省略号,或者在 subtitle/subtitleDescription 的情况下需要视图。我想以编程方式使用自动布局。

与此类似:

  _________________________________
 |[title]                         | 
 |[subtitle][subtitleDescription] |
 |________________________________|

我希望标签位于左上角而不是居中。在我现在的代码中,它都是居中的,所有的标签都在彼此之上。

我只是在所有UILabel 上调用sizeToFit,除此之外我根本不调整框架。当然,这段代码是在我分配和初始化标签并设置文本之后。这是我的代码:

 - (void)setup
 
[self.title sizeToFit];
[self.subtitle sizeToFit];
[self.subtitleDescription sizeToFit];

[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[title]-(>=0)-|"
                                                            options:kNilOptions
                                                           metrics:nil
                                                             views:@ @"title" : self.title ]];

[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[subtitle]-5-[subdesc]-(>=0)-|"
                                                             options:NSLayoutFormatDirectionLeftToRight
                                                             metrics:nil
                                                               views:@ @"subtitle" : self.subtitle,
                                                                        @"subdesc"  : self.subtitleDescription ]];

// compR > compR
[self setContentCompressionResistancePriority:900 forAxis:UILayoutConstraintAxisHorizontal];
[self setContentCompressionResistancePriority:500 forAxis:UILayoutConstraintAxisHorizontal];

[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[title]-5-[subtitle]|"
                                                             options:kNilOptions
                                                             metrics:nil
                                                               views:@ @"title"    : self.title,
                                                                        @"subtitle" : self.subtitle ]];

[self addConstraint:[NSLayoutConstraint constraintWithItem:self.subtitleDescription
                                                 attribute:NSLayoutAttributeBaseline
                                                 relatedBy:NSLayoutRelationEqual
                                                    toItem:self.subtitle
                                                 attribute:NSLayoutAttributeBaseline
                                                multiplier:1.0
                                                  constant:0]];
 

谢谢!!!

这是视图的屏幕截图:

更新

正如 jrturton 向我指出的那样,看起来我的所有约束都从约束异常中被打破了。我想弄清楚为什么它们坏了。给出的消息是“无法同时满足约束”。

【问题讨论】:

您能否显示此代码生成的布局的屏幕截图? 我在别的地方使用这个类的时候,我把frame设置为(0, 0, 300, 300),这个view在300 x和y的范围内居中。 看起来这些标签太大而无法放入该视图,您是否在日志中看到约束异常? 老实说,如果你必须从代码中完成,我会创建一个 puppet 项目,使用界面生成器拖放相同的布局,然后从正在运行的应用程序中,我会将所有约束都 NSLog 到控制台和在此基础上设置生产应用程序的约束。 @ZoltanVaradi 这是一个糟糕的建议!这种布局可以通过三个 VFL 语句来实现。 【参考方案1】:

首先,通过设置translatesAutoResizingMaskIntoConstraints = NO,确保您的标签启用了自动布局。

您不需要任何sizeToFit 调用。在添加约束时,它们是没有意义的。标签将在布局点使用其固有大小。

为防止居中,请不要固定在超级视图的两侧。所以不要这样:

"|[title]-(>=0)-|"

这样做:

"|[title]"

或者确实是这样:

"|[title]|"

并在标签上设置左对齐。

对于一行中的多个标签,您需要这样:

"|[subtitle]-5-[subdesc]|"

在选项中传递NSLayoutFormatAlignAllBaseline。如果需要,您可以将选项组合在一起 (|)。同样,您不需要不等式间距。左对齐标签将占用尽可能多的空间。您可能希望在两个标签上设置压缩阻力/拥抱优先级,这样如果没有足够的空间来显示这两个值,您就有规则截断哪个标签。

您在视图本身上设置内容压缩阻力,如果视图本身也不受自动布局的影响,这将毫无意义。您还将两次设置为两个不同的值,我不确定您希望通过它实现什么。

如果超级视图具有固定大小,您当前的垂直约束将导致一个或其他标签被拉伸以填充剩余大小,这将使文本垂直居中,这就是标签太高时所做的事情。

你可以通过不固定到底部来克服这个问题:

"V:[title]-5-[subtitle]"

我写了大量关于 VFL 和自动布局here 的文章,并附有其他自动布局相关文章的链接。

【讨论】:

非常感谢!我犯了很多小错误。谢谢您的帮助。我将 translatesAutoResizingMaskIntoConstraints 设置为 YES。我正在调整这个意见超级视图。加上一些小细节。

以上是关于如何以编程方式使用自动布局排列这三个 UILabel?的主要内容,如果未能解决你的问题,请参考以下文章

如何以编程方式使用自动布局添加自定义视图

如何使用自动布局水平设置三个按钮而没有间隙

以编程方式自动布局不起作用

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

如何使用自动布局以编程方式创建 UITableView?

如何以编程方式添加标签并以编程方式使用自动布局定位它