我正在创建一个显示各种静态文本元素的iOS视图。 xib看起来像这样:
它为标题,时间戳,正文和页脚使用四个标签。每个视图都垂直固定在其上方的同级视图中,并锚定在父视图的左/右侧。所有标签都具有固定高度,除了具有> =高度的主体和设置为0的行数,其中“自动换行”作为换行样式。父视图是UIScrollView。
在iPhone上它看起来很好:
然而在iPad上它看起来像这样:
咦?身体标签中所有额外的垂直空间来自何处? xib及其视图控制器在iPhone和iPad之间是相同的(目前没有自定义的iPad代码)。我发现垂直空间与标签渲染的换行数直接相关。如果没有线条包裹,则没有额外的垂直空间。如果只有几条线包裹,则会有一些额外的垂直空间。如果几乎每一条线都包裹起来,那就是它的样子。
首先,有关UILabel为何如此表现的想法?
其次,如果我不能停止这样做,我该如何解决呢?
我已经尝试了一些事情。如果我在-viewDidLayoutSubViews中调用[bodyLabel sizeToFit],那么它会修复标签但不修复任何兄弟视图的布局(例如,页脚标签卡在屏幕底部而不是拉到下面身体)。调用sizeToFit后,任何尝试让整个视图重新布局其子项的操作都将被忽略。我还尝试通过基于字体计算高度来调整UILabel的大小,这导致与-sizeToFit相同的行为(虽然代码更多)。
用UITextView替换Body UILabel并不会给我带来奇怪的垂直间距问题但是我需要手动计算UITextView的高度(使用字体计算)以及在父UIScrollView中调整UITextView的大小使得它如此UIScrollView只是拒绝滚动(就好像它不知道它的内容对于它的边界来说太大了)。
所以此刻我被困住了。即使只是解释为什么 UILabel在iPad布局上的行为方式也会有所帮助。
答案 0 :(得分:4)
如果其他人使用autolayout遇到同样的问题...我可能已经能够通过创建约束来解决同样的问题,正如Coche建议的那样,但我意识到我的preferredMaxLayoutWidth
太小了设置在uilabel上。一旦我设置了准确的preferredMaxLayoutWidth
(标签的实际宽度),顶部和底部的间距就会消失。
答案 1 :(得分:3)
主要问题是自动调整Label内部文本大小的方法失败了,因为在iPad中,Label从一开始就没有设置宽度,它是在运行时计算的,这是该混乱的来源。在iPhone上,由于你的标签有一个设定的宽度(在IB上),没有麻烦。
有两种方法可以解决问题:
有两个故事板:一个用于iPhone,一个用于iPad
这样做会使你的Label从一开始就知道它的宽度,它就像在iPhone上一样。
只有一个适用于iPhone和iPad的故事板
您可以通过计算最适合其文本的大小来解决该问题,并且该结果通过代码向Label添加高度约束。要计算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)]];