5

我正在创建一个显示各种静态文本元素的 iOS 视图。xib 看起来像这样:

在此处输入图像描述

它为标题、时间戳、正文和页脚使用四个标签。每个视图都垂直锚定在其上方的同级视图上,并锚定在父视图的左侧/右侧。所有标签都有一个固定的高度,除了具有 >= 高度的主体和设置为 0 的行数,“自动换行”作为换行样式。父视图是 UIScrollView。

在 iPhone 上看起来不错:

iPhone开始滚动 iPhone 滚动结束

但是在 iPad 上它看起来像这样:

iPad 开始滚动 iPad 滚动结束

嗯?正文标签中所有额外的垂直空间是从哪里来的?xib 及其视图控制器在 iPhone 和 iPad 之间是相同的(目前没有自定义 iPad 代码)。我发现垂直空间与标签渲染的换行数直接相关。如果没有换行,则没有额外的垂直空间。如果只有几行环绕,就会有一点额外的垂直空间。如果几乎每一行都换行,好吧,这就是它的样子。

首先,关于为什么 UILabel 会有这种行为的任何想法?

其次,如果我不能让它停止这样做,我该如何解决它?

我已经尝试了几件事。如果我在 -viewDidLayoutSubViews 中调用 [bodyLabel sizeToFit] 那么它会修复标签但不会修复任何同级视图的布局(例如,页脚标签卡在屏幕底部而不是拉到正下方身体)。任何在调用 sizeToFit 后让整个视图重新布局其子视图的尝试都将被忽略。我还尝试通过基于字体计算高度来调整 UILabel 的大小,这导致与 -sizeToFit 相同的行为(尽管有更多代码)。

用 UITextView 替换 Body UILabel 不会给我带来奇怪的垂直间距问题,但我需要手动计算 UITextView 的高度(使用字体计算),并且在父 UIScrollView 中调整 UITextView 的大小使得 UIScrollView 变得简单拒绝滚动(好像它不知道它的内容对于它的边界来说太大了)。

所以此刻我被困住了。即使只是解释为什么UILabel 在 iPad 布局上以这种方式表现也会有所帮助。

4

2 回答 2

4

万一其他人使用自动布局遇到同样的问题......我可能已经能够通过创建 Coche 建议的约束来解决同样的问题,但我意识到我preferredMaxLayoutWidth在 uilabel 上的设置太小了。一旦我设置了一个准确preferredMaxLayoutWidth的(标签的实际宽度),顶部和底部的间距就消失了。

于 2014-04-03T19:59:16.257 回答
3

主要问题是自动调整标签内文本大小的方法失败了,因为在 iPad 中,标签从一开始就没有设定宽度,它是在运行时计算的,这就是混乱的根源。在 iPhone 上,由于您的 Label 具有设定的宽度(在 IB 上),因此没有问题。

解决问题有两种方法:

  1. 有两个故事板:一个用于 iPhone,一个用于 iPad

    这样做将使您的标签从一开始就知道它的宽度,并且它就像在 iPhone 上一样工作。 在此处输入图像描述

  2. iPhone 和 iPad 都只有一个 Storyboard

    您可以通过计算最适合其文本的大小来解决该问题,然后通过代码向标签添加高度约束。为了计算desiredSize,您可以使用以下公式计算宽度:Current View's width - (Leading space + Trailing Space)。这是我的代码

CGSize desiredSize = [_bodyLabel sizeThatFits:CGSizeMake(self.view.frame.size.width-40, 10)];
NSString *visualContraint = [NSString stringWithFormat:@"V:[_bodyLabel(%.0f)]",desiredSize.height];
[_bodyLabel addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:visualContraint
                                                                   options:NSLayoutFormatDirectionLeadingToTrailing
                                                                   metrics:nil
                                                                     views:NSDictionaryOfVariableBindings(_bodyLabel)]];

在此处输入图像描述

于 2013-09-05T07:57:46.737 回答