在UILabel中将文本垂直对齐到顶部 [英] Vertically align text to top within a UILabel

查看:169
本文介绍了在UILabel中将文本垂直对齐到顶部的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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



解决方案

没有办法设置垂直对齐a UILabel ,但您可以通过更改标签的框架获得相同的效果。



这是快速简单的方法:

  [myLabel sizeToFit]; 






如果您的标签包含较长的文字,行,将 numberOfLines 设置为 0 (零表示无限数量的行)。

  myLabel.numberOfLines = 0; 
[myLabel sizeToFit];






长版本 b
$ b

我将在代码中创建我的标签,以便您可以看到发生了什么。你可以在Interface Builder中设置大部分。我的设置是一个基于视图的应用程序与背景图像我在Photoshop中显示边距(20点)。

   - (void)viewDidLoad 
{
[super viewDidLoad];

// 20点顶部和左边距。尺寸离开20 pt在右边。
CGRect labelFrame = CGRectMake(20,20,280,150);
UILabel * myLabel = [[UILabel alloc] initWithFrame:labelFrame];
[myLabel setBackgroundColor:[UIColor orangeColor]];

NSString * labelText = @我是现代少将的典范,我有蔬菜,动物和矿物的信息;
[myLabel setText:labelText];

//告诉标签使用无限数目的行
[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;
//将框架宽度调整为280(320 - 边距)
// width也可以是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 在评论中使用自动布局修复了NIB和故事板:


如果您的标签包含在nib或storyboard中作为使用autolayout的ViewController的视图的子视图, code> 调用 viewDidLoad 将无法工作,因为autolayout大小和位置 viewDidLoad ,并立即撤销 sizeToFit 调用的效果。但是, viewDidLayoutSubviews 之内调用 sizeToFit 可以工作。




我的原始答案(用于后代/参考)



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



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

  CGSize maximumSize = CGSizeMake(300,9999); 
NSString * dateString = @今天是1999年1月1日;
UIFont * dateFont = [UIFont fontWithName:@Helveticasize:14];
CGSize dateStringSize = [dateString sizeWithFont:dateFont
constrainedToSize:maximumSize
lineBreakMode:self.dateLabel.lineBreakMode];

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

self.dateLabel.frame = dateFrame;

此页面对于同一个解决方案有一些不同的代码:



苹果中的讨论


I have a UILabel with space for two lines of text. Sometimes, when the text is too short, this text is displayed in the vertical center of the label.

How do I vertically align the text to always be at the top of the UILabel?

解决方案

There's no way to set the vertical align on a UILabel, but you can get the same effect by changing the label's frame. I've made my labels orange so you can see clearly what's happening.

Here's the quick and easy way to do this:

    [myLabel sizeToFit];


If you have a label with longer text that will make more than one line, set numberOfLines to 0 (zero here means an unlimited number of lines).

    myLabel.numberOfLines = 0;
    [myLabel sizeToFit];


Longer Version

I'll make my label in code so that you can see what's going on. You can set up most of this in Interface Builder too. My setup is a View Based App with a background image I made in Photoshop to show margins (20 points). The label is an attractive orange color so you can see what's going on with the dimensions.

- (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];
}

Some limitations of using sizeToFit come into play with center- or right-aligned text. Here's what happens:

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

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

The label is still sized with a fixed top-left corner. You can save the original label's width in a variable and set it after sizeToFit, or give it a fixed width to counter these problems:

    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;


Note that sizeToFit will respect your initial label's minimum width. If you start with a label 100 wide and call sizeToFit on it, it will give you back a (possibly very tall) label with 100 (or a little less) width. You might want to set your label to the minimum width you want before resizing.

Some other things to note:

Whether lineBreakMode is respected depends on how it's set. NSLineBreakByTruncatingTail (the default) is ignored after sizeToFit, as are the other two truncation modes (head and middle). NSLineBreakByClipping is also ignored. NSLineBreakByCharWrapping works as usual. The frame width is still narrowed to fit to the rightmost letter.


Mark Amery gave a fix for NIBs and Storyboards using Auto Layout in the comments:

If your label is included in a nib or storyboard as a subview of the view of a ViewController that uses autolayout, then putting your sizeToFit call into viewDidLoad won't work, because autolayout sizes and positions the subviews after viewDidLoad is called and will immediately undo the effects of your sizeToFit call. However, calling sizeToFit from within viewDidLayoutSubviews will work.


My Original Answer (for posterity/reference):

This uses the NSString method sizeWithFont:constrainedToSize:lineBreakMode: to calculate the frame height needed to fit a string, then sets the origin and width.

Resize the frame for the label using the text you want to insert. That way you can accommodate any number of lines.

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;

This page has some different code for the same solution:

discussions in apple

这篇关于在UILabel中将文本垂直对齐到顶部的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆