iOS:自动布局中的多行UILabel

Jam*_*rpe 178 iphone cocoa-touch uilabel ios autolayout

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

在此输入图像描述

顶部标签是标题标签,我不知道它会有多少行.我需要标题标签来显示所有文本行.我还需要另外两个标签和小图像放在标题正下方,不管它有多高.我在标签和小图像之间设置了垂直间距约束,在标题标签和超视图之间设置了顶部间距约束,在小图像和超级视图之间设置了底部间距约束.白色UIView没有高度约束,因此它应该垂直拉伸以包含其子视图.我已将标题标签的行数设置为0.

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

我怎样才能做到这一点?

mwh*_*uss 250

使用-setPreferredMaxLayoutWidthUILabel和自动版式应该处理其余部分.

[label setPreferredMaxLayoutWidth:200.0];
Run Code Online (Sandbox Code Playgroud)

请参阅UILabel文档.

更新:

只需要将storyboard中的高度约束设置为大于或等于",不需要setPreferredMaxLayoutWidth.

  • 同时将IB中的高度约束设置为大于或等于". (12认同)
  • 提醒:请记住设置numberOfLines属性. (9认同)
  • 好的,无论如何要在界面构建器中执行此操作? (8认同)
  • 有关如何确定`preferredMaxLayoutWidth`的信息,请参见http://stackoverflow.com/a/29180323/1529675,并参见http://devetc.org/code/2014/07/07/auto-layout-and-views-that-wrap .html是一个简短但内容丰富的文章,有动画GIF(不是我的写作,我是通过谷歌发现的) (4认同)
  • 是的,使用你想要的最大宽度. (2认同)

Cha*_* Wu 212

将标签集的行数扩展为0,更重要的是将自动布局设置高度扩展为> = x.自动布局将完成剩下的工作.您可能还包含基于前一个元素的其他元素,以便正确定位.

自动布局


Ant*_*sov 45

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

多行文本的内在内容大小

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

由于我们通常不提前知道这个值,因此我们需要采取两步法来实现这一目标.首先我们让Auto Layout完成它的工作,然后我们在布局过程中使用结果框来再次更新首选的最大宽度和触发器布局.

- (void)layoutSubviews
{
    [super layoutSubviews];
    myLabel.preferredMaxLayoutWidth = myLabel.frame.size.width;
    [super layoutSubviews];
}
Run Code Online (Sandbox Code Playgroud)

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

我们也可以在标签子类本身中执行此操作:

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

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

要从视图控制器级别进行此调整,我们将挂钩到viewDidLayoutSubviews.此时,第一个自动布局通道的帧已经设置,我们可以使用它们来设置首选的最大宽度.

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

最后,确保标签上没有明确的高度约束,其优先级高于标签的内容压缩阻力优先级.否则它将胜过内容的计算高度.确保检查可能影响标签高度的所有约束.


Cor*_*eke 16

我只是在与这个确切的场景作斗争,但还有更多的视图需要调整大小并在必要时向下移动.这让我疯了,但我终于明白了.

这是关键:当您添加和移动视图时,Interface Builder喜欢引入额外的约束,您可能不会注意到.在我的情况下,我有一个视图中间有一个额外的约束,指定它和它的超级视图之间的大小,基本上固定到那一点.这意味着它上面没有任何东西可以调整大小,因为它会违反这个限制.

判断是否是这种情况的简单方法是尝试手动调整标签大小.IB让你成长吗?如果是,请按照您的预期移动下面的标签吗?确保在调整大小之前检查了这两个,以查看约束如何移动视图:

IB菜单

如果视图卡住,请按照其下方的视图进行操作,并确保其中一个视图没有超视图约束的顶部空间.然后只需确保标签的行数选项设置为0,它应该处理其余部分.


Chr*_*ris 5

我发现您需要以下条件:

  • 首要约束
  • 前导约束(例如左侧)
  • 尾随约束(例如右侧)
  • 将内容设置为具有优先级,将水平设置为低,因此如果文本较短,它将填充给定的空间。
  • 将内容压缩阻力(水平方向)设置为低,以便环绕而不是尝试变宽。
  • 将行数设置为0。
  • 将换行模式设置为自动换行。