将文本垂直alignment到UILabel中的顶部

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

如何将文本垂直alignment,始终位于UILabel的顶部?

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

没有办法在UILabel上设置垂直alignment方式,但是通过改变标签的框架可以得到相同的效果。 我已经把我的标签做成了橙色,所以你可以清楚地看到发生了什么。

以下是快速简单的方法:

  [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一些限制与中心或右alignment的文本发挥作用。 以下是发生的事情:

  // myLabel.textAlignment = NSTextAlignmentRight; myLabel.textAlignment = NSTextAlignmentCenter; [myLabel setNumberOfLines:0]; [myLabel sizeToFit]; 

在这里输入图像描述

标签的大小仍然固定在左上angular。 您可以将原始标签的宽度保存在一个variables中,并将其设置在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(或者更小)。 在resize之前,您可能需要将标签设置为所需的最小宽度。

通过调整帧宽度来校正标签对齐

其他一些事情要注意:

lineBreakMode是否受到尊重取决于它的设置。 与其他两种截断模式(head和middle) sizeToFitNSLineBreakByTruncatingTail (默认值)在sizeToFit之后被忽略。 NSLineBreakByClipping也被忽略。 NSLineBreakByCharWrapping像往常一样工作。 框架宽度仍然缩小以适合最右边的字母。


Mark Amery在评论中使用“自动布局”对NIB和Storyboard进行了修复:

如果您的标签作为使用自动布局的ViewController的view的子视图包含在笔尖或故事板中,那么将您的sizeToFit调用放入viewDidLoad将不起作用,因为自动布局调整了viewDidLoad之后的子视图的大小和位置,并立即撤消你的sizeToFit调用的效果。 但是,从viewDidLayoutSubviews调用sizeToFit 工作。


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

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

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

 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; 
  1. 设置新的文本:

     myLabel.text = @"Some Text" 
  2. maximum numbermaximum number设置为0(自动):

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

     myLabel.frame = CGRectMake(20,20,200,800) 
  4. 调用sizeToFit减less帧的大小,所以内容恰好适合:

     [myLabel sizeToFit] 

标签框架现在只是高和宽足以适合您的文字。 左上angular应该保持不变。 我只用左上angularalignment的文本进行了testing。 对于其他路线,您可能必须稍后修改框架。

另外,我的标签已启用换行。

参考扩展解决scheme:

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

应该被replace

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

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

类似地,alignBottom也应该用@" \n@%"代替"\n@%" (对于循环初始化必须replace为“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文本分配后。

以防万一任何人的帮助,我有同样的问题,但能够解决这个问题,只需从使用UILabel切换到使用UITextView 。 我很欣赏这不适合每个人,因为function有点不同。

如果切换到使用UITextView ,则可以closures所有的滚动视图属性以及启用用户交互…这将强制它更像一个标签。

在这里输入图像描述

就像上面的答案一样,但是这不是很正确,或者很简单,我就把它清理了一下。 将这个扩展添加到它自己的.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 

然后使用,将您的文本放入标签,然后调用适当的方法来alignment它:

 [myLabel alignTop]; 

要么

 [myLabel alignBottom]; 

没有麻烦,没有大惊小怪

 @interface MFTopAlignedLabel : UILabel @end @implementation MFTopAlignedLabel - (void)drawTextInRect:(CGRect) rect { NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:self.text attributes:@{NSFontAttributeName:self.font}]; rect.size.height = [attributedText boundingRectWithSize:rect.size options:NSStringDrawingUsesLineFragmentOrigin context:nil].size.height; if (self.numberOfLines != 0) { rect.size.height = MIN(rect.size.height, self.numberOfLines * self.font.lineHeight); } [super drawTextInRect:rect]; } @end 

没有麻烦,没有Objective-C,没有大惊小怪,但斯威夫特3:

 class VerticalTopAlignLabel: UILabel { override func drawText(in rect:CGRect) { guard let labelText = text else { return super.drawText(in: rect) } let attributedText = NSAttributedString(string: labelText, attributes: [NSFontAttributeName: font]) var newRect = rect newRect.size.height = attributedText.boundingRect(with: rect.size, options: .usesLineFragmentOrigin, context: nil).size.height if numberOfLines != 0 { newRect.size.height = min(newRect.size.height, CGFloat(numberOfLines) * font.lineHeight) } super.drawText(in: newRect) } } 

一个更快(更肮脏)的方式来实现这一点是通过设置UILabel的换行符模式为“剪辑”,并添加一个固定数量的换行符。

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

这个解决scheme并不适用于所有人 – 特别是如果你还想在string末尾显示“…”,如果它超出你显示的行数,你需要使用代码的较长位 – 但在很多情况下,这会得到你所需要的。

而不是UILabel你可以使用UITextField有垂直alignment选项:

 textField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter; textField.userInteractionEnabled = NO; // Don't allow interaction 

我一直在努力争取这个很长一段时间,我想分享我的解决scheme。

这会给你一个UILabel ,它会自动将文本缩小到0.5个比例,并垂直居中文本。 这些选项也可以在Storyboard / IB中使用。

 [labelObject setMinimumScaleFactor:0.5]; [labelObject setBaselineAdjustment:UIBaselineAdjustmentAlignCenters]; 

创build一个新的类

LabelTopAlign

.h文件

 #import <UIKit/UIKit.h> @interface KwLabelTopAlign : UILabel { } @end 

.m文件

 #import "KwLabelTopAlign.h" @implementation KwLabelTopAlign - (void)drawTextInRect:(CGRect)rect { int lineHeight = [@"IglL" sizeWithFont:self.font constrainedToSize:CGSizeMake(rect.size.width, 9999.0f)].height; if(rect.size.height >= lineHeight) { int textHeight = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(rect.size.width, rect.size.height)].height; int yMax = textHeight; if (self.numberOfLines > 0) { yMax = MIN(lineHeight*self.numberOfLines, yMax); } [super drawTextInRect:CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, yMax)]; } } @end 

编辑

这是一个简单的实现,

 #import "KwLabelTopAlign.h" @implementation KwLabelTopAlign - (void)drawTextInRect:(CGRect)rect { CGFloat height = [self.text sizeWithFont:self.font constrainedToSize:rect.size lineBreakMode:self.lineBreakMode].height; if (self.numberOfLines != 0) { height = MIN(height, self.font.lineHeight * self.numberOfLines); } rect.size.height = MIN(rect.size.height, height); [super drawTextInRect:rect]; } @end 

在这里输入图像描述

在界面生成器

  • UILabel设置为最大可能文本的大小
  • 在属性检查器中将Lines设置为“0”

在你的代码中

  • 设置标签的文字
  • 在您的标签上调用sizeToFit

代码片段:

 self.myLabel.text = @"Short Title"; [self.myLabel sizeToFit]; 

创buildUILabel的子类。 奇迹般有效:

 // TopLeftLabel.h #import <Foundation/Foundation.h> @interface TopLeftLabel : UILabel { } @end // TopLeftLabel.m #import "TopLeftLabel.h" @implementation TopLeftLabel - (id)initWithFrame:(CGRect)frame { return [super initWithFrame:frame]; } - (CGRect)textRectForBounds:(CGRect)bounds limitedToNumberOfLines:(NSInteger)numberOfLines { CGRect textRect = [super textRectForBounds:bounds limitedToNumberOfLines:numberOfLines]; textRect.origin.y = bounds.origin.y; return textRect; } -(void)drawTextInRect:(CGRect)requestedRect { CGRect actualRect = [self textRectForBounds:requestedRect limitedToNumberOfLines:self.numberOfLines]; [super drawTextInRect:actualRect]; } @end 

如这里所讨论的。

我写了一个util函数来达到这个目的。 你可以看看:

 //调整多行标签的高度,使其与顶部垂直alignment
 +(void)alignLabelWithTop:(UILabel *)label {
   CGSize maxSize = CGSizeMake(label.frame.size.width,999);
   label.adjustsFontSizeToFitWidth = NO;

   //得到实际的高度
   CGSize actualSize = [label.text sizeWithFont:label.font constrainedToSize:maxSize lineBreakMode:label.lineBreakMode];
   CGRect rect = label.frame;
   rect.size.height = actualSize.height;
   label.frame = rect;
 }

。如何使用? (如果lblHello是由Interface Builder创build的,那么我跳过一些UILabel属性的细节)

 lblHello.text = @“Hello World!Hello World!Hello World!Hello World!Hello World!Hello World!Hello World!Hello World!
 lblHello.numberOfLines = 5;
 [Utils alignLabelWithTop:lblHello];

我也写在我的博客作为一篇文章: http : //fstoke.me/blog/?p=2819

我花了一段时间阅读代码,以及介绍页面中的代码,发现他们都试图修改标签的框架大小,以便默认的中心垂直alignment不会出现。

但是,在某些情况下,我们希望标签占据所有这些空间,即使标签的文本太多(例如多行高度相同)。

在这里,我用另一种方法来解决它,只需在标签的末尾添加换行符(请注意,我实际上是inheritance了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 "]; } 

对于自适应UI(iOS8或之后),UILabel的垂直alignment将通过更改属性noOfLines = 0来从StoryBoard中设置;

约束

  1. 调整UILabel LefMargin,RightMargin和Top Margin约束。

  2. 更改Content Compression Resistance Priority For Vertical = 1000`所以垂直>水平。

UILabel的约束

编辑:

 noOfLines=0 

并且以下约束条件足以达到预期的结果。

在这里输入图像描述

我在这里提出了build议,并创build了一个可以包装UILabel的视图,并将其大小并设置行数以使其顶部alignment。 简单地把一个UILabel作为子视图:

 @interface TopAlignedLabelContainer : UIView { } @end @implementation TopAlignedLabelContainer - (void)layoutSubviews { CGRect bounds = self.bounds; for (UILabel *label in [self subviews]) { if ([label isKindOfClass:[UILabel class]]) { CGSize fontSize = [label.text sizeWithFont:label.font]; CGSize textSize = [label.text sizeWithFont:label.font constrainedToSize:bounds.size lineBreakMode:label.lineBreakMode]; label.numberOfLines = textSize.height / fontSize.height; label.frame = CGRectMake(0, 0, textSize.width, fontSize.height * label.numberOfLines); } } } @end 

你可以使用TTTAttributedLabel ,它支持垂直alignment。

 @property (nonatomic) TTTAttributedLabel* label; <...> //view's or viewController's init method _label.verticalAlignment = TTTAttributedLabelVerticalAlignmentTop; 

我发现在这个问题上的答案现在有点过时了,所以添加这个为自动布局粉丝在那里。

自动布局使这个问题相当微不足道。 假设我们将标签添加到UIView *view ,下面的代码将完成这个:

 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 ),标签将在view的顶部沿水平方向进行边缘到边缘的定位。

我想有一个标签,它可以有多行,最小的字体大小,并在父视图中水平和垂直居中。 我以编程方式将我的标签添加到我的视图中:

 - (void) customInit { // Setup label self.label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)]; self.label.numberOfLines = 0; self.label.lineBreakMode = UILineBreakModeWordWrap; self.label.textAlignment = UITextAlignmentCenter; // Add the label as a subview self.autoresizesSubviews = YES; [self addSubview:self.label]; } 

然后当我想改变我的标签的文字…

 - (void) updateDisplay:(NSString *)text { if (![text isEqualToString:self.label.text]) { // Calculate the font size to use (save to label's font) CGSize textConstrainedSize = CGSizeMake(self.frame.size.width, INT_MAX); self.label.font = [UIFont systemFontOfSize:TICKER_FONT_SIZE]; CGSize textSize = [text sizeWithFont:self.label.font constrainedToSize:textConstrainedSize]; while (textSize.height > self.frame.size.height && self.label.font.pointSize > TICKER_MINIMUM_FONT_SIZE) { self.label.font = [UIFont systemFontOfSize:self.label.font.pointSize-1]; textSize = [ticker.blurb sizeWithFont:self.label.font constrainedToSize:textConstrainedSize]; } // In cases where the frame is still too large (when we're exceeding minimum font size), // use the views size if (textSize.height > self.frame.size.height) { textSize = [text sizeWithFont:self.label.font constrainedToSize:self.frame.size]; } // Draw self.label.frame = CGRectMake(0, self.frame.size.height/2 - textSize.height/2, self.frame.size.width, textSize.height); self.label.text = text; } [self setNeedsDisplay]; } 

希望帮助别人!

FXLabel(在github上)通过将label.contentMode设置为UIViewContentModeTop来完成这项工作。 这个组件不是我自己制作的,但是它是我经常使用的一个组件,并且有很多特性,而且似乎工作的很好。

我已经使用了很多上面的方法,只是想添加一个我已经使用的快捷方式:

 myLabel.text = [NSString stringWithFormat:@"%@\n\n\n\n\n\n\n\n\n",@"My label text string"]; 

确保string中的换行符的数量将导致任何文本填充可用的垂直空间,并设置UILabel以截断任何溢出的文本。

因为有时候够好够好

对于阅读此内容的人来说,因为标签内的文本不是垂直居中的,所以请记住,某些字体types的devise不是同等的。 例如,如果您创build了zapfino大小为16的标签,则会看到文本不是完全垂直居中。

然而,使用helvetica会垂直居中文本。

子类UILabel并约束绘制矩形,如下所示:

 - (void)drawTextInRect:(CGRect)rect { CGSize sizeThatFits = [self sizeThatFits:rect.size]; rect.size.height = MIN(rect.size.height, sizeThatFits.height); [super drawTextInRect:rect]; } 

我尝试了涉及换行符的解决scheme,并在某些情况下遇到了不正确的行为。 根据我的经验,像上面那样限制绘制矩形比混乱numberOfLines更容易。

PS你可以想像这样轻松地支持UIViewContentMode:

 - (void)drawTextInRect:(CGRect)rect { CGSize sizeThatFits = [self sizeThatFits:rect.size]; if (self.contentMode == UIViewContentModeTop) { rect.size.height = MIN(rect.size.height, sizeThatFits.height); } else if (self.contentMode == UIViewContentModeBottom) { rect.origin.y = MAX(0, rect.size.height - sizeThatFits.height); rect.size.height = MIN(rect.size.height, sizeThatFits.height); } [super drawTextInRect:rect]; } 

如果使用自动布局,请将代码或IB中的垂直contentHuggingPriority设置为1000。 在IB中,您可能必须通过将其优先级设置为1,然后将其删除来删除高度限制。

只要你没有做任何复杂的任务,你可以使用UITextView而不是UILabels

禁用滚动。

如果你想要显示的文本完全只是用户sizeToFitsizeThatFits:方法

如果创build自己的自定义视图是一个选项,你可以做这样的事情:

 - (void)drawRect:(CGRect)rect { CGRect bounds = self.bounds; [self.textColor set]; [self.text drawInRect:bounds withFont:self.font lineBreakMode:UILineBreakModeTailTruncation alignment:self.textAlignment]; } 

这是一个旧的解决scheme,在iOS> = 6上使用自动布局

我的解决scheme
1 /自行分割线(忽略标签包装设置)
2 /自己画线(忽略标签alignment)

 @interface UITopAlignedLabel : UILabel @end 
 @implementation UITopAlignedLabel #pragma mark Instance methods - (NSArray*)splitTextToLines:(NSUInteger)maxLines { float width = self.frame.size.width; NSArray* words = [self.text componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; NSMutableArray* lines = [NSMutableArray array]; NSMutableString* buffer = [NSMutableString string]; NSMutableString* currentLine = [NSMutableString string]; for (NSString* word in words) { if ([buffer length] > 0) { [buffer appendString:@" "]; } [buffer appendString:word]; if (maxLines > 0 && [lines count] == maxLines - 1) { [currentLine setString:buffer]; continue; } float bufferWidth = [buffer sizeWithFont:self.font].width; if (bufferWidth < width) { [currentLine setString:buffer]; } else { [lines addObject:[NSString stringWithString:currentLine]]; [buffer setString:word]; [currentLine setString:buffer]; } } if ([currentLine length] > 0) { [lines addObject:[NSString stringWithString:currentLine]]; } return lines; } - (void)drawRect:(CGRect)rect { if ([self.text length] == 0) { return; } CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetFillColorWithColor(context, self.textColor.CGColor); CGContextSetShadowWithColor(context, self.shadowOffset, 0.0f, self.shadowColor.CGColor); NSArray* lines = [self splitTextToLines:self.numberOfLines]; NSUInteger numLines = [lines count]; CGSize size = self.frame.size; CGPoint origin = CGPointMake(0.0f, 0.0f); for (NSUInteger i = 0; i < numLines; i++) { NSString* line = [lines objectAtIndex:i]; if (i == numLines - 1) { [line drawAtPoint:origin forWidth:size.width withFont:self.font lineBreakMode:UILineBreakModeTailTruncation]; } else { [line drawAtPoint:origin forWidth:size.width withFont:self.font lineBreakMode:UILineBreakModeClip]; } origin.y += self.font.lineHeight; if (origin.y >= size.height) { return; } } } @end 

I riffed off dalewking's suggestion and added a UIEdgeInset to allow for an adjustable margin. nice work around.

 - (id)init { if (self = [super init]) { contentEdgeInsets = UIEdgeInsetsZero; } return self; } - (void)layoutSubviews { CGRect localBounds = self.bounds; localBounds = CGRectMake(MAX(0, localBounds.origin.x + contentEdgeInsets.left), MAX(0, localBounds.origin.y + contentEdgeInsets.top), MIN(localBounds.size.width, localBounds.size.width - (contentEdgeInsets.left + contentEdgeInsets.right)), MIN(localBounds.size.height, localBounds.size.height - (contentEdgeInsets.top + contentEdgeInsets.bottom))); for (UIView *subview in self.subviews) { if ([subview isKindOfClass:[UILabel class]]) { UILabel *label = (UILabel*)subview; CGSize lineSize = [label.text sizeWithFont:label.font]; CGSize sizeForText = [label.text sizeWithFont:label.font constrainedToSize:localBounds.size lineBreakMode:label.lineBreakMode]; NSInteger numberOfLines = ceilf(sizeForText.height/lineSize.height); label.numberOfLines = numberOfLines; label.frame = CGRectMake(MAX(0, contentEdgeInsets.left), MAX(0, contentEdgeInsets.top), localBounds.size.width, MIN(localBounds.size.height, lineSize.height * numberOfLines)); } } } 

I was working on that particular problem as well, so I've taken the ideas by DS and nevan king and basically combined them into a subclass that implements a vertical alignment property, which also allows you to change the alignment more than just once. It borrows the UIControlContentVerticalAlignment type and also supports UIControlContentVerticalAlignmentFill .

From what I've seen, numberOfLines seems to be useless when it comes to vertical alignment, so in this subclass it is always set to 0 when applying vertical alignment. Also, you still have to set lineBreakMode yourself in case you want a multi-line text label.

There it is: QALabel on GitHub

In UILabel vertically text alignment is not possible. But, you can dynamically change the height of the label using sizeWithFont: method of NSString , and just set its x and y as you want.

You can use UITextField . It supports the contentVerticalAlignment peoperty as it is a subclass of UIControl . You have to set its userInteractionEnabled to NO to prevent user from typing text on it.