我有一个UILabel
,有两行文字的空间。有时,当文本太短时,这些文本会显示在标签的垂直中心。
我如何将文本垂直对齐,使其总是在`UILabel'的顶部?
。
没有办法在`UILabel'上设置垂直对齐,但你可以通过改变标签的框架得到同样的效果。我把我的标签做成橙色,这样你就可以清楚地看到发生了什么。
下面是快速和简单的方法,可以做到这一点。
[myLabel sizeToFit];
如果你有一个文本较长的标签,将使其超过一行,请将numberOfLines
设为0
(这里的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
照常工作。框架的宽度仍然被缩小以适应最右边的字母。
<hr
Mark Amery 在评论中给出了一个针对使用自动布局的NIB和故事板的修正:
如果你的标签作为使用自动布局的ViewController的
view
的子视图被包含在nib或storyboard中,那么将sizeToFit
的调用放在viewDidLoad
中不会起作用,因为自动布局在viewDidLoad
被调用后会对子视图进行尺寸和位置调整,会立即撤销sizeToFit
调用的效果。然而,在viewDidLayoutSubviews'中调用
sizeToFit'将**工作。
<hr 我的原始答案(供后人/参考):
这使用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;
就像上面的答案一样,但它不是很正确,也不容易塞进代码,所以我把它清理了一下。 把这个扩展名添加到它自己的.h和.m文件中,或者直接粘贴在你打算使用它的实现上面。
#pragma mark VerticalAlign
@interface UILabel (VerticalAlign)
- (void)alignTop;
- (void)alignBottom;
@end
@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
然后在使用时,把你的文本放到标签里,然后调用适当的方法来对齐它。
[myLabel alignTop];
或
[myLabel alignBottom];
我花了点时间阅读代码,以及介绍页面中的代码,发现它们都试图修改标签的框架尺寸,这样就不会出现默认的中心垂直对齐。
然而,在某些情况下,我们确实希望标签占据所有这些空间,即使标签确实有这么多的文字(例如,多行等高)。
在这里,我使用了另一种方法来解决这个问题,就是简单地将换行符垫在标签的末尾(请注意,我实际上是继承了UILabel
,但这不是必须的)。
CGSize fontSize = [self.text sizeWithFont:self.font];
finalHeight = fontSize.height * self.numberOfLines;
finalWidth = 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 "];
}