当前位置: 首页 > 知识库问答 >
问题:

iOS:自动布局中的多行UILabel

翁宏茂
2023-03-14

我在尝试用自动布局实现一些非常基本的布局行为时遇到了困难。我的视图控制器在IB中看起来是这样的:

最上面的标签是标题标签,不知道会有多少行。我需要标题标签显示所有的文字行。我还需要另外两个标签和小的图像,以布局的权利下面的标题,但它恰巧是高的。我设置了标签和小图像之间的垂直间距约束,以及标题标签和它的超级视图之间的顶部间距约束和小图像和它的超级视图之间的底部间距约束。白色UIView没有高度限制,因此它应该垂直拉伸以包含其子视图。我已将标题标签的行数设置为0。

如何调整标题标签的大小以适应字符串所需的行数?我的理解是我不能使用setFrame方法,因为我使用的是自动布局。而且我必须使用自动布局,因为我需要那些其他视图留在标题标签下面(因此有约束)。

我怎么才能让这一切发生?

共有3个答案

史鹏云
2023-03-14

来源:http://www.objc.io/issue-3/advanced-auto-layout-toolbox.html

多行文本的内在内容大小

对于多行文本,UILabel和NSTextField的内在内容大小是不明确的。文本的高度取决于线条的宽度,这还有待于在求解约束条件时确定。为了解决这个问题,两个类都有一个名为preferredMaxLayoutWidth的新属性,它指定了计算内在内容大小的最大线宽。

因为我们通常事先不知道这个值,所以我们需要采取两步走的方法来正确地得到这个值。首先,我们让Auto Layout完成它的工作,然后在Layout pass中使用结果帧更新首选的最大宽度并再次触发Layout。

- (void)layoutSubviews
{
    [super layoutSubviews];
    myLabel.preferredMaxLayoutWidth = myLabel.frame.size.width;
    [super layoutSubviews];
}

第一次调用[super layoutSubviews]是标签获取其框架集所必需的,而第二次调用是更改后更新布局所必需的。如果省略第二个调用,则会出现NSInternalInconsistencyException错误,因为我们在布局传递中进行了更改,需要更新约束,但我们没有再次触发布局。

我们也可以在label子类本身中这样做:

@implementation MyLabel
- (void)layoutSubviews
{
    self.preferredMaxLayoutWidth = self.frame.size.width;
    [super layoutSubviews];
}
@end

在这种情况下,我们不需要首先调用[super layoutSubviews],因为当调用layoutSubviews时,我们已经在标签本身上有了一个框架

要从视图控制器级别进行此调整,我们挂钩到ViewDidLayoutSubViews。在这一点上,第一个自动布局的框架已经设置,我们可以使用它们来设置首选的最大宽度。

- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];
    myLabel.preferredMaxLayoutWidth = myLabel.frame.size.width;
    [self.view layoutIfNeeded];
}

最后,请确保标签上没有显式的高度限制,该限制的优先级高于标签的内容抗压缩优先级。否则它将超过计算出的内容高度。确保检查所有能影响标签高度的约束条件。

微生学
2023-03-14

扩展您的标签,设置行数为0,更重要的是自动布局,设置高度为>=X。自动布局将做剩下的。您也可以根据前一个元素包含其他元素,以便正确定位。

宋涵衍
2023-03-14

上使用 ,然后autolayout将处理其余的内容。

[label setPreferredMaxLayoutWidth:200.0];

请参阅PreferredMaxLayOutwidth上的UILabel文档。

更新:

只需要将情节提要中的 约束设置为 ,不需要设置PreferredMaxLayOutwidth。

 类似资料:
  • 下面的问题是这个问题的延续: iOS:自动布局中的多行 UI标签 主要思想是,每个视图都应该声明其“首选”(固有)大小,以便AutoLayout可以知道如何正确显示它。UILabel只是视图本身无法知道显示所需的大小的情况的一个例子。这取决于提供的宽度。 正如mwhuss所指出的,setPreferredMaxLayoutWidth实现了使标签跨越多行的技巧。但这不是这里的主要问题。问题是,我在何

  • 在过去的几天里,我试图使用自动布局约束完成一个相当简单(至少应该是这样)的布局,但没有成功。 我的视图层次结构是:< br> UIScrollView - UIView(容器视图)< br> - UILabel(多行标签)< br >-ui webview < br >-ui label < br >-ui button 所需的功能是根据内容的大小扩展容器视图。为了增加UIWebView的高度,我

  • 我正在尝试学习自动布局,当这件事发生时,我最终认为我已经掌握了它。我正在玩原型细胞和标签。我正在尝试 < li >标题,< code>titleLbl -图片中的蓝色方框 < li >货币,< code>moneyLbl -图片中的绿色方框 < li >副标题/描述,< code >副标题< code> -图片中的红色方框 到目前为止,我有这个: 我想实现的是: 绿色框应始终完全显示在1行 绿色框

  •     你可能用过UIViewAutoresizingMask类型的一些常量,应用于当父视图改变尺寸的时候,相应UIView的frame也跟着更新的场景(通常用于横竖屏切换)。     在iOS6中,苹果介绍了自动排版机制,它和自动调整不同,并且更加复杂。     在Mac OS平台,CALayer有一个叫做layoutManager的属性可以通过CALayoutManager协议和CAConst

  • 我注意到在iOS10 Beta 5(即将尝试Beta 6)中,AutoLayout约束动画的行为有点不同。 例如,此方法的工作原理与以前的iOS版本不同: 。。。在我的测试中,最初用添加约束(addConstraints)添加的约束也将在iOS 10中用UIView(UIView)来设置动画(animateWithDuration)(block)。。。到目前为止,这导致了一些古怪/不受欢迎的行为。

  • 我以前从未使用过自动布局约束。我有一个新的小应用程序,我正在开发,并注意到NIB的视图默认为自动布局。所以,我想我会借此机会使用它,并尝试弄清楚苹果公司在这方面的进展。 第一个挑战: 我需要调整MKMapView的大小,并将其设置为新位置的动画。如果我按照我习惯的方式来做: ...然后,每当更新同级视图时,MKMapView将“捕捉”回其原始高度(在我的例子中,UISegmentedControl