将文本垂直对齐到UILabel中的顶部

我有一个用于两行文本的UILabel 。 有时,当文本太短时,该文本显示在标签的垂直中心。

如何将文字垂直对齐以始终位于UILabel的顶部?

图像代表一个垂直居中文本的UILabel


没有办法在UILabel上设置垂直对齐,但您可以通过更改标签的框架来获得相同的效果。 我已将我的标签制成橙色,以便您清楚地看到发生了什么。

以下是快速简单的方法:

    [myLabel sizeToFit];

sizeToFit挤压标签


如果您的文本长度超过一行,则将numberOfLines设置为0 (这里的零代表无​​限制的行数)。

    myLabel.numberOfLines = 0;
    [myLabel sizeToFit];

使用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是否受到尊重取决于它的设置。 与其他两种截断模式(头部和中部) sizeToFitNSLineBreakByTruncatingTail (默认值)在sizeToFit之后被忽略。 NSLineBreakByClipping也被忽略。 NSLineBreakByCharWrapping运作。 框架宽度仍然缩小以适合最右边的字母。


Mark Amery在评论中使用Auto Layout对NIB和Storyboard进行了修复:

如果您的标签被包括在笔尖或故事板作为一个子视图view使用自动布局,然后把你的一个视图控制器的sizeToFit呼叫到viewDidLoad是行不通的,因为自动布局大小和位置后子视图viewDidLoad被调用,将立即取消你的sizeToFit调用的效果。 但是,从viewDidLayoutSubviews调用sizeToFit将起作用。


我的原始答复(后人/参考):

这使用NSString方法sizeWithFont:constrainedToSize: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 = @"Some Text"
    
  • maximum numbermaximum number设置为0(自动):

    myLabel.numberOfLines = 0
    
  • 将标签的框架设置为最大尺寸:

    myLabel.frame = CGRectMake(20,20,200,800)
    
  • 调用sizeToFit以减小帧大小,以便内容适合:

    [myLabel sizeToFit]
    
  • 标签框架现在只是高和宽足以适合您的文本。 左上角应该保持不变。 我只用左上角对齐的文本测试了这一点。 对于其他路线,您可能必须稍后修改框架。

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


    参考扩展解决方案:

    for(int i=1; i< newLinesToPad; i++) 
        self.text = [self.text stringByAppendingString:@"n"];
    

    应该被替换

    for(int i=0; i<newLinesToPad; i++)
        self.text = [self.text stringByAppendingString:@"n "];
    

    在每个添加的换行符中都需要额外的空间,因为iPhone UILabels的拖尾回车似乎被忽略:(

    类似地,alignBottom也应该用@" n@%"代替"n@%" (用于循环初始化必须替换为“for(int i = 0 ...”))。

    以下扩展适用于我:

    // -- file: UILabel+VerticalAlign.h
    #pragma mark VerticalAlign
    @interface UILabel (VerticalAlign)
    - (void)alignTop;
    - (void)alignBottom;
    @end
    
    // -- file: UILabel+VerticalAlign.m
    @implementation UILabel (VerticalAlign)
    - (void)alignTop {
        CGSize fontSize = [self.text sizeWithFont:self.font];
        double finalHeight = fontSize.height * self.numberOfLines;
        double finalWidth = self.frame.size.width;    //expected width of label
        CGSize theStringSize = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(finalWidth, finalHeight) lineBreakMode:self.lineBreakMode];
        int newLinesToPad = (finalHeight  - theStringSize.height) / fontSize.height;
        for(int i=0; i<newLinesToPad; i++)
            self.text = [self.text stringByAppendingString:@"n "];
    }
    
    - (void)alignBottom {
        CGSize fontSize = [self.text sizeWithFont:self.font];
        double finalHeight = fontSize.height * self.numberOfLines;
        double finalWidth = self.frame.size.width;    //expected width of label
        CGSize theStringSize = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(finalWidth, finalHeight) lineBreakMode:self.lineBreakMode];
        int newLinesToPad = (finalHeight  - theStringSize.height) / fontSize.height;
        for(int i=0; i<newLinesToPad; i++)
            self.text = [NSString stringWithFormat:@" n%@",self.text];
    }
    @end
    

    然后调用[yourLabel alignTop];[yourLabel alignBottom]; 在每个yourLabel文本分配之后。

    链接地址: http://www.djcxy.com/p/735.html

    上一篇: Vertically align text to top within a UILabel

    下一篇: Finding the index of an item given a list containing it in Python