我有一个UILabel,它有两行文字的空间。有时,当文本太短时,此文本会显示在标签的垂直中心。

如何垂直对齐文本,使其始终位于UILabel的顶部?


当前回答

对于那些使用自定义表单元格试图解决此问题的人,请将其添加到自定义表单元格类中:

斯威夫特2.2:

override func layoutSubviews() {
    labelName.sizeToFit()
}

这解决了我的问题。

其他回答

一种更快(更脏)的方法是将UILabel的换行模式设置为“Clip”并添加固定数量的换行符。

myLabel.lineBreakMode = UILineBreakModeClip;
myLabel.text = [displayString stringByAppendingString:"\n\n\n\n"];

这种解决方案不适用于所有人——特别是,如果您仍然希望在字符串末尾显示“…”,如果它超过了您要显示的行数,则需要使用较长的代码段之一——但在很多情况下,这将满足您的需要。

无法在UILabel上设置垂直对齐,但可以通过更改标签的框架来获得相同的效果。我把我的标签做成橙色,这样你就能清楚地看到发生了什么。

以下是快速简便的方法:

    [myLabel sizeToFit];


如果您有一个包含多行的较长文本的标签,请将numberOfLines设置为0(此处零表示无限行数)。

    myLabel.numberOfLines = 0;
    [myLabel sizeToFit];


更长版本

我将在代码中制作标签,这样您就可以看到发生了什么。您也可以在Interface Builder中设置大部分内容。我的设置是一个基于视图的应用程序,带有我在Photoshop中制作的背景图像,以显示边距(20分)。标签是诱人的橙色,因此您可以看到尺寸的变化。

- (void)viewDidLoad
{
    [super viewDidLoad];

    // 20 point top and left margin. Sized to leave 20 pt at right.
    CGRect labelFrame = CGRectMake(20, 20, 280, 150);
    UILabel *myLabel = [[UILabel alloc] initWithFrame:labelFrame];
    [myLabel setBackgroundColor:[UIColor orangeColor]];

    NSString *labelText = @"I am the very model of a modern Major-General, I've information vegetable, animal, and mineral";
    [myLabel setText:labelText];

    // Tell the label to use an unlimited number of lines
    [myLabel setNumberOfLines:0];
    [myLabel sizeToFit];

    [self.view addSubview:myLabel];
}

使用sizeToFit的一些限制会影响居中或右对齐的文本。以下是发生的情况:

    // myLabel.textAlignment = NSTextAlignmentRight;
    myLabel.textAlignment = NSTextAlignmentCenter;

    [myLabel setNumberOfLines:0];
    [myLabel sizeToFit];

标签的大小仍然是固定的左上角。您可以将原始标签的宽度保存在变量中,并在sizeToFit之后进行设置,或者为其设置固定宽度以解决这些问题:

    myLabel.textAlignment = NSTextAlignmentCenter;

    [myLabel setNumberOfLines:0];
    [myLabel sizeToFit];

    CGRect myFrame = myLabel.frame;
    // Resize the frame's width to 280 (320 - margins)
    // width could also be myOriginalLabelFrame.size.width
    myFrame = CGRectMake(myFrame.origin.x, myFrame.origin.y, 280, myFrame.size.height);
    myLabel.frame = myFrame;


请注意,sizeToFit将尊重初始标签的最小宽度。如果您从一个100宽的标签开始,并在其上调用sizeToFit,那么它将返回一个100(或稍小)宽的标签(可能非常高)。在调整大小之前,您可能需要将标签设置为所需的最小宽度。

需要注意的其他事项:

是否遵守lineBreakMode取决于其设置方式。NSLineBreakByTruncatingTail(默认值)在sizeToFit之后被忽略,其他两种截断模式(头部和中部)也是如此。NSLineBreakByClipping也被忽略。NSLineBreakByCharWrapping照常工作。框架宽度仍然变窄,以适合最右边的字母。


Mark Amery在评论中使用Auto Layout修复了NIB和Storyboards:

如果标签包含在笔尖或情节提要中,作为使用自动布局的ViewController视图的子视图,那么将sizeToFit调用放入viewDidLoad将不起作用,因为在调用viewDidLoad后自动布局将调整子视图的大小和位置,并将立即撤消sizeToFit调用的效果。但是,从viewDidLayoutSubviews内调用sizeToFit将起作用。

我的原始答案(供后人参考):

这使用NSString方法sizeWithFont:consainedToSize:lineBreakMode:计算适合字符串所需的框架高度,然后设置原点和宽度。

使用要插入的文本调整标签的框架大小。这样您可以容纳任意数量的行。

CGSize maximumSize = CGSizeMake(300, 9999);
NSString *dateString = @"The date today is January 1st, 1999";
UIFont *dateFont = [UIFont fontWithName:@"Helvetica" size:14];
CGSize dateStringSize = [dateString sizeWithFont:dateFont 
        constrainedToSize:maximumSize 
        lineBreakMode:self.dateLabel.lineBreakMode];

CGRect dateFrame = CGRectMake(10, 10, 300, dateStringSize.height);

self.dateLabel.frame = dateFrame;

设置新文本:myLabel.text=@“某些文本”将最大行数设置为0(自动):myLabel.numberOfLines=0将标签的框架设置为最大大小:myLabel.frame=CGRectMake(20,20200800)调用sizeToFit以减小框架大小,使内容刚好适合:[myLabel sizeToFit]

标签框架现在刚好足够高和宽,以适合您的文本。左上角应保持不变。我只测试了左上对齐的文本。对于其他路线,您可能需要随后修改框架。

此外,我的标签启用了换行。

只要不执行任何复杂任务,就可以使用UITextView而不是UILabels。

禁用滚动。

如果希望文本完全显示,只需使用sizeToFit和sizeThatFits:methods

我发现这个问题的答案现在有点过时了,所以为汽车布局爱好者添加这个。

自动布局使这个问题变得非常微不足道。假设我们要将标签添加到UIView*视图中,以下代码将完成此操作:

UILabel *label = [[UILabel alloc] initWithFrame:CGRectZero];
[label setText:@"Some text here"];
[label setTranslatesAutoresizingMaskIntoConstraints:NO];
[view addSubview:label];

[view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[label]|" options:0 metrics:nil views:@{@"label": label}]];
[view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[label]" options:0 metrics:nil views:@{@"label": label}]];

标签的高度将自动计算(使用其intrinsicContentSize),标签将在视图顶部水平放置。