iOS:多行 uilabel 仅显示带有自动布局的一行
Posted
技术标签:
【中文标题】iOS:多行 uilabel 仅显示带有自动布局的一行【英文标题】:iOS: multiline uilabel only shows one line with autolayout 【发布时间】:2013-02-24 23:46:16 【问题描述】:我认为下面的代码应该会导致一个多行标签,然后是一个按钮,但是,在布局之后,只有一行标签显示出来。虽然我可以在垂直布局中放置一个明确的高度,但这会破坏目的。关于我应该应用哪些其他限制的任何想法?
UILabel *lbExplain = [[UILabel alloc] init];
lbExplain.text = @"The Sync process allows you to synchronize your library between different devices. By clicking on the button below you can find other devices to sync with. The other device also has to be running this applicaton.";
lbExplain.lineBreakMode = NSLineBreakByWordWrapping;
lbExplain.numberOfLines = 0;
lbExplain.translatesAutoresizingMaskIntoConstraints = NO;
UIButton *btnPartner = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[btnPartner setTitle:@"Look for Partners" forState:UIControlStateNormal];
[btnPartner addTarget:self action:@selector(findPartners:) forControlEvents:UIControlEventTouchUpInside];
btnPartner.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:lbExplain];
[self.view addSubview:btnPartner];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[lbExplain]-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(lbExplain)]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[lbExplain]-[btnPartner]" options:NSLayoutFormatAlignAllLeft metrics:nil views:NSDictionaryOfVariableBindings(lbExplain, btnPartner)]];
【问题讨论】:
如果你在标签上调用-sizeToFit
会发生什么?
我无法立即看到缺少的东西。如果你在 IB 中做基本相同的事情,它就可以正常工作。
【参考方案1】:
添加行:
lbExplain.preferredMaxLayoutWidth = 280;
这必须是在 IB 中自动完成的事情,因为如果您在此处设置标签会正确展开。您传递给它的数字似乎对它如何垂直扩展很重要,但它不会覆盖您为宽度设置的约束。
编辑后:
如果我在 updateViewConstraints 中添加该行,并将数字与视图的边界相关联,效果会更好。这样它可以在旋转时正确调整。
-(void)updateViewConstraints
[super updateViewConstraints];
lbExplain.preferredMaxLayoutWidth = self.view.bounds.size.width - 40;
【讨论】:
谢谢!这实际上有效,尽管我对为什么有点困惑? 280 似乎是一个神奇的数字,但它适用于 iPad 和 iphone(ipad 当然比 280 宽得多)。 它真的可以在 iPad 上工作,即使你旋转? 280 只是 320 减去您设置的边的两个 20 点空间(默认)。我注意到在 iPhone 上旋转时,标签以文本上方和下方的空白结束。 如果主要在 iPad 上运行。 ipad 和 iphone 似乎基本上都按照纵向屏幕的高度来调整大小,因此它们在更宽的横向视图中在上方和下方留下了额外的空间。不理想,但比剪辑的文本更好。 抱歉,在上次回复之前错过了您的编辑。你是对的,这是更一致的。还必须将其添加到“didRotateFromInterfaceOrientation”,以使其随方向而变化。它并不完全流畅,但很实用。 将 updateViewConstraints 的实现替换为 - (void)viewWillLayoutSubviews self.explaination.preferredMaxLayoutWidth = self.view.bounds.size.width - 40;这对我有用,updateViewConstraints 没有在旋转时调用,但布局子视图是。【参考方案2】:这里的问题是preferredMaxLayoutWidth
没有设置。因此,文本不受任何宽度的限制,因此不会换行到下一行。
我发现在 Autolayout 中使用多行 UILabel
的最简单方法是创建一个子类:
@interface MyMultilineLabel : UILabel
@end
@implementation MyMultilineLabel
- (void)setBounds:(CGRect)bounds
[super setBounds:bounds];
CGFloat width = CGRectGetWidth(bounds);
if (self.preferredMaxLayoutWidth != width)
self.preferredMaxLayoutWidth = width;
- (id)initWithFrame:(CGRect)frame
self = [super initWithFrame:frame];
if (self)
self.lineBreakMode = NSLineBreakByWordWrapping;
self.numberOfLines = 0;
return self;
@end
【讨论】:
【参考方案3】:你确定你没有不明确的布局吗?
你可以在你的代码中做一个测试,比如
if ([self.view hasAmbiguousLayout])
NSLog(@"ambiguous");
或在模拟器或测试设备上暂停并输入控制台:
po [[UIWindow keyWindow] _autolayoutTrace]
如果是这样,你可能想尝试让你的约束更明确一点(乍一看,高度是模棱两可的):
@"V:|-[lbExplain]-[btnPartner]-|"
或
@"V:|-[lbExplain(==300)]-[btnPartner(==200)]"
这是视觉格式语言的文档:
http://developer.apple.com/library/mac/#documentation/UserExperience/Conceptual/AutolayoutPG/Articles/formatLanguage.html
【讨论】:
OP 的约束并不模糊,因为标签和按钮具有固有的高度。至于你的第二个建议,这就是他试图避免的(设置明确的高度)。 AUILabel
只有在一行时才具有固有大小。【参考方案4】:
我有一个类似的问题,UITableViewCell 中的多行标签,使用 AutoLayout 定位,不会自行扩展。
它在 UITableView 内,使用 UITableViewAutomaticDimension 和 estimatedHeightForRowAtIndexPath 方法“自动”处理尺寸。 (我认为这可能是问题的根源)
我通过调用解决了这个问题:
[cell layoutIfNeeded]
在 cellForRowAtIndexPath 方法中,就在返回单元格之前。
它就像一个魅力!
【讨论】:
以上是关于iOS:多行 uilabel 仅显示带有自动布局的一行的主要内容,如果未能解决你的问题,请参考以下文章
如何在通知内容扩展中使用多行 UILabel / 自动布局调试布局