Вертикально выровнять текст на вершину внутри UILabel -- ios поле с участием cocoa-touch поле с участием uikit поле с участием uilabel поле с участием text-alignment пол Связанный проблема

Vertically align text to top within a UILabel


2223
vote

проблема

русский

У меня есть <код> UILabel с пространством для двух строк текста. Иногда, когда текст слишком короткий, этот текст отображается в вертикальном центре метки.

Как вертикально выровнять текст, чтобы всегда быть в верхней части <код> UILabel ?

Изображение, представляющее собой UILabel с вертикально центрированным текстом« SRC = »https://i.stack.imgur.com/txzmg.jpg

Английский оригинал

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?

image representing a UILabel with vertically-centered text

</div
              
 
 

Список ответов

2721
 
vote
vote
Лучший ответ
 

Нет способа установить вертикальное выравнивание на <код> UILabel , но вы можете получить тот же эффект, изменяя рамку метки. Я сделал свои ярлыки оранжевыми, чтобы вы могли четко видеть, что происходит.

Вот быстрый и простой способ сделать это:

 <код>     [myLabel sizeToFit];   

sizetofit, чтобы сжать метку


Если у вас есть метка с более длинным текстом, который сделает более одной строки, установить <код> numberOfLines на <код> 0 (ноль здесь означает неограниченное количество строк).

.
 <код>     myLabel.numberOfLines = 0;     [myLabel sizeToFit];   

более длительный текст метки с помощью sizetofit


<Сильная> более длинная версия

Я сделаю свой ярлык в коде, чтобы вы могли видеть, что происходит. Вы можете настроить большую часть этого в интерфейсе 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;   

Выравнивание метки


Обратите внимание, что <код> [myLabel sizeToFit]; 0 будет уважать минимальную ширину вашей исходной метки. Если вы начнете с этикетки 100 шириной и звоните <код> [myLabel sizeToFit]; 1 на нем, он вернет вас обратно (возможно, очень высокую) ярлык с 100 (или немного меньше) шириной. Возможно, вы захотите установить вашу метку на минимальную ширину, которую вы хотите разместить до изменения размера.

Исправьте выравнивание метки, изменяя ширину кадра

Некоторые другие вещи, чтобы примечание:

<код> [myLabel sizeToFit]; 2 уважается, зависит от того, как он установлен. <Код> [myLabel sizeToFit]; 3 (по умолчанию) игнорируется после <код> [myLabel sizeToFit]; 4 , как и два других мода усечения (голова и середина). <Код> [myLabel sizeToFit]; 5 также игнорируется. <Код> [myLabel sizeToFit]; 6 работает как обычно. Ширина кадра все еще сужается, чтобы соответствовать самой правой букве.


Mark Amery дал решение для расслаителей и раскалков, используя автоматическую макет в комментариях:

Если ваша этикетка включена в NiB или раскащенную доску как субвезон <код> [myLabel sizeToFit]; 7 из viewcontroller, который использует autolayout, а затем помещать <код> [myLabel sizeToFit]; 8 call in [myLabel sizeToFit]; 9 не будет работать, поскольку autolayout размеры и позиции подзрены после <код> numberOfLines0 и будут немедленно отменить эффекты вашего <код> numberOfLines1 call. Тем не менее, вызывая <код> numberOfLines2 из <код> numberOfLines3 будет работать.


<сильный> мой оригинальный ответ (для потомки / ссылки):

Это использует <код> numberOfLines4 Метод <код> numberOfLines5 для расчета высоты кадра, необходимая для установки строки, затем устанавливает начало и ширину.

Измените размер кадра для метки, используя текст, который вы хотите вставить. Таким образом, вы можете разместить любое количество строк.

 <код> numberOfLines6  

 

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

sizeToFit to squeeze a label


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 label text with 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]; 

enter image description here

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; 

label alignment


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.

Correct label alignment by resizing the frame width

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; 
</div
 
 
         
         
338
 
vote
  1. Установите новый текст:

     <код> myLabel.text = @"Some Text"   
  2. Установите <код> maximum number строк до 0 (автоматический):

     <код> myLabel.numberOfLines = 0   
  3. Установите рамку метки до максимального размера:

     <Код> myLabel.frame = CGRectMake(20,20,200,800)   
  4. Вызов <код> sizeToFit , чтобы уменьшить размер кадра, чтобы содержимое только что соответствовало:

     <Код> [myLabel sizeToFit]   

Рама ярлыки теперь просто высокая и достаточно широкая, чтобы соответствовать вашему тексту. Слева от верхней части должна быть без изменений. Я проверил это только с верхним выровним левым текстом. Для других выравниваний вам может придеться модифицировать кадр позже.

Кроме того, моя этикетка имеет включенную упаковку слов.

 
  1. Set the new text:

    myLabel.text = @"Some Text" 
  2. Set the maximum number of lines to 0 (automatic):

    myLabel.numberOfLines = 0 
  3. Set the frame of the label to the maximum size:

    myLabel.frame = CGRectMake(20,20,200,800) 
  4. Call sizeToFit to reduce the frame size so the contents just fit:

    [myLabel sizeToFit] 

The labels frame is now just high and wide enough to fit your text. The top left should be unchanged. I have tested this only with the top left-aligned text. For other alignments, you might have to modify the frame afterward.

Also, my label has word wrapping enabled.

</div
 
 
         
         
161
 
vote

Ссылаясь на расширение решения:

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

должен быть заменен на

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

Дополнительное пространство необходимо в каждой добавленной новой строке, потому что iPhone UILabels 'Training Rebse возвращает: (

Аналогично, alignbottom должен быть обновлен тоже с <кодом> @" @%" вместо maximum number0 (для инициализации цикла должен быть заменен "для (int i = 0 ..." тоже).

Для меня следующие продолжение:

 <код> maximum number1  

Тогда звоните <код> maximum number2 или <код> maximum number3 После каждого вашего текстового назначения вашего текста.

 

Refering to the extension solution:

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

should be replaced by

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

Additional space is needed in every added newline, because iPhone UILabels' trailing carriage returns seems to be ignored :(

Similarly, alignBottom should be updated too with a @" @%" in place of " @%" (for cycle initialization must be replaced by "for(int i=0..." too).

The following extension works for me:

// -- 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:@"  "]; }  - (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:@"  %@",self.text]; } @end 

Then call [yourLabel alignTop]; or [yourLabel alignBottom]; after each yourLabel text assignment.

</div
 
 
         
         
151
 
vote

На всякий случай, это какая-либо помощь, у меня была такая же проблема, но смогла решить проблему, просто переключая с использованием maximum number4 для использования <код> maximum number5 . Я ценю это не для всех, потому что функциональность немного отличается.

Если вы переключитесь на использование maximum number6 , вы можете отключить все свойства просмотра просмотра, а также включенные взаимодействие пользователя ... Это заставит его действовать больше похожи на этикетку.

Введите описание изображения здесь

 

Just in case it's of any help to anyone, I had the same problem but was able to solve the issue simply by switching from using UILabel to using UITextView. I appreciate this isn't for everyone because the functionality is a bit different.

If you do switch to using UITextView, you can turn off all the Scroll View properties as well as User Interaction Enabled... This will force it to act more like a label.

enter image description here

</div
 
 
         
         
130
 
vote

Нет мозги, без суеты

 <код> maximum number7  

no muss, нет объекта c, без суеты, но Swift 3:

 <код> maximum number8  

<Сильные> Свифт 4.2

 <код> maximum number9  
 

No muss, no fuss

@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 

No muss, no Objective-c, no fuss but Swift 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)     }  } 

Swift 4.2

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: [NSAttributedString.Key.font: 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)     }  } 
</div
 
 
     
     
81
 
vote

Как и ответ выше, но это было не совсем правильно, или легко ударить в код, поэтому я немного убрал его. Добавьте это расширение либо на свой собственный файл .h и .m или просто вставьте прямо выше реализации, которую вы намерены его использовать:

 <код> myLabel.numberOfLines = 0 0  

А потом использовать, поместите текст в метку, а затем вызовите подходящий метод, чтобы выровнять его:

 <код> myLabel.numberOfLines = 0 1  

или

 <код> myLabel.numberOfLines = 0 2  
 

Like the answer above, but it wasn't quite right, or easy to slap into code so I cleaned it up a bit. Add this extension either to it's own .h and .m file or just paste right above the implementation you intend to use it:

#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:@"  "];     } }  - (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:@"  %@",self.text];     } } @end 

And then to use, put your text into the label, and then call the appropriate method to align it:

[myLabel alignTop]; 

or

[myLabel alignBottom]; 
</div
 
 
 
 
75
 
vote

<Сильный> Простые подход с использованием раскадровки:

Встраиваемая этикетка в StackView и установить следующие два атрибута StackView в инспекторе атрибута:

1- <Код> myLabel.numberOfLines = 0 3 <Код> myLabel.numberOfLines = 0 4 ,

2- <Код> myLabel.numberOfLines = 0 5 <Код> myLabel.numberOfLines = 0 6

Введите описание изображения здесь

 

Easiest approach using Storyboard:

Embed Label in a StackView and set the following two attributes of StackView in the Attribute Inspector:

1- Axis to Horizontal,

2- Alignment to Top

enter image description here

</div
 
 
       
       
71
 
vote

Еще быстрее (и грязный) способ выполнить это, установлена ​​режимом перерыва линии UILabel в «CLIP» и добавление фиксированного количества новых линий.

 <код> myLabel.lineBreakMode = UILineBreakModeClip; myLabel.text = [displayString stringByAppendingString:"    "];   

Это решение не будет работать для всех - в частности, если вы все еще хотите показать «...» в конце своей строки, если он превышает количество строк, которые вы отображаете, вам нужно Используйте один из более длинных битов кода - но для многих случаев это заставит вас, что вам нужно.

 

An even quicker (and dirtier) way to accomplish this is by setting the UILabel's line break mode to "Clip" and adding a fixed amount of newlines.

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

This solution won't work for everyone -- in particular, if you still want to show "..." at the end of your string if it exceeds the number of lines you're showing, you'll need to use one of the longer bits of code -- but for a lot of cases this'll get you what you need.

</div
 
 
   
   
62
 
vote

вместо <Кода> UILabel Вы можете использовать <код> UITextField , который имеет вертикальный вариант выравнивания:

 <код> textField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter; textField.userInteractionEnabled = NO; // Don't allow interaction   
 

Instead of UILabel you may use UITextField which has vertical alignment option:

textField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter; textField.userInteractionEnabled = NO; // Don't allow interaction 
</div
 
 
   
   
52
 
vote

Я боролся с этим в течение длительного времени, и я хотел поделиться своим решением.

Это даст вам <код> UILabel , который будет автоматическим текстом до 0,5 масштабов и вертикально центрам текста. Эти параметры также доступны в раскаренной доске / IB.

 <код> [labelObject setMinimumScaleFactor:0.5]; [labelObject setBaselineAdjustment:UIBaselineAdjustmentAlignCenters];   
 

I've struggled with this one for a long time and I wanted to share my solution.

This will give you a UILabel that will autoshrink text down to 0.5 scales and vertically center the text. These options are also available in Storyboard/IB.

[labelObject setMinimumScaleFactor:0.5]; [labelObject setBaselineAdjustment:UIBaselineAdjustmentAlignCenters]; 
</div
 
 
 
 
45
 
vote

Создать новый класс

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   
 

Create a new class

LabelTopAlign

.h file

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

.m file

#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 

Edit

Here's a simpler implementation that does the same:

#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 
</div
 
 
 
 
40
 
vote

Введите описание изображения здесь

в интерфейсе Builder

    .
  • Установите <код> UILabel на размер самый большой возможный текст
  • Установите <код> UILabel0 на '0' в атрибутах инспектор

в вашем коде

    .
  • Установите текст этикетки
  • Вызов <код> UILabel1 на лейбл

Кодовый фрагмент:

 <код> UILabel2  
 

enter image description here

In Interface Builder

  • Set UILabel to size of biggest possible Text
  • Set Lines to '0' in Attributes Inspector

In your code

  • Set the text of the label
  • Call sizeToFit on your label

Code Snippet:

self.myLabel.text = @"Short Title"; [self.myLabel sizeToFit]; 
</div
 
 
 
 
37
 
vote

для адаптивного интерфейса UI (iOS8 или после), вертикальное выравнивание UILabel должно быть установлено из раскадровки, изменив свойства. <Код> UILabel3 = 0` и

<Сильные> ограничения

  1. Регулировка UILabel Lefmargin, rightmargin и верхние ограничения маржи.

  2. Изменить <код> UILabel4 = 1000`, так что вертикальный & GT; горизонтальный.

ограничения UILabel

отредактировано:

 <код> UILabel5  

и следующие ограничения достаточно для достижения желаемых результатов.

Введите описание изображения здесь

 

For Adaptive UI(iOS8 or after) , Vertical Alignment of UILabel is to be set from StoryBoard by Changing the properties noOfLines=0` and

Constraints

  1. Adjusting UILabel LefMargin, RightMargin and Top Margin Constraints.

  2. Change Content Compression Resistance Priority For Vertical=1000` So that Vertical>Horizontal .

Constraints of UILabel

Edited:

noOfLines=0 

and the following constraints are enough to achieve the desired results.

enter image description here

</div
 
 
 
 
35
 
vote

Создайте подкласс UILABEL. Работает как очарование:

 <код> UILabel6  

Как обсуждено Здесь .

 

Create a subclass of UILabel. Works like a charm:

// 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 

As discussed here.

</div
 
 
29
 
vote

Я написал функцию UTIL для достижения этой цели. Вы можете посмотреть:

. // Отрегулируйте высоту многострочной этикетки, чтобы сделать его выровнять вертикальные с вершинами + (void) alignlabelwithtop: (uilabel *) label {   CGSIZE MAXSIZE = CGSIZEMAKE (MALK.SIZE.size.width, 999);   label.adjustsfontsizetofitwidth = no;    // получить фактическую высоту   CGSIZE ACTUALSIZE = [MALK.TEXT SIZEWITHFONT: LABLE.FONT ConstructionTosize: Maxsize Linebreakmode: Label.linebreakmode];   CGRECT RELECT = Label.Frame;   rect.size.height = ActualSize.height;   Label.Frame = RECT; } 

. Как использовать? (Если lblhello создается построителем интерфейса, поэтому я пропускаю некоторые детали атрибутов 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

 

I wrote a util function to achieve this purpose. You can take a look:

 // adjust the height of a multi-line label to make it align vertical with top + (void) alignLabelWithTop:(UILabel *)label {   CGSize maxSize = CGSizeMake(label.frame.size.width, 999);   label.adjustsFontSizeToFitWidth = NO;    // get actual height   CGSize actualSize = [label.text sizeWithFont:label.font constrainedToSize:maxSize lineBreakMode:label.lineBreakMode];   CGRect rect = label.frame;   rect.size.height = actualSize.height;   label.frame = rect; } 

.How to use? (If lblHello is created by Interface builder, so I skip some UILabel attributes detail)

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

I also wrote it on my blog as an article: http://fstoke.me/blog/?p=2819

</div
 
 
27
 
vote

Я занял некоторое время, чтобы прочитать код, а также код на введенной странице и обнаружил, что все они пытаются изменить размер кадра метки, так что вертикальное выравнивание центра по умолчанию не появится.

Однако в некоторых случаях мы хотим, чтобы этикетка занимала все эти пробелы, даже если этикетка имеет такой большой текст (например, несколько строк с равной высотой).

Здесь я использовал альтернативный способ решить его, просто прокладка новых линий до конца этикетки (пожалуйста, обратите внимание, что я фактически унаследовал <код> 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:@"  "]; }   
 

I took a while to read the code, as well as the code in the introduced page, and found that they all try to modify the frame size of label, so that the default center vertical alignment would not appear.

However, in some cases we do want the label to occupy all those spaces, even if the label does have so much text (e.g. multiple rows with equal height).

Here, I used an alternative way to solve it, by simply pad newlines to the end of label (pls note that I actually inherited the UILabel, but it is not necessary):

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:@"  "]; } 
</div
 
 
23
 
vote

Что я сделал в своем приложении, было установить свойство линии UILabel в 0, а также создать нижнее ограничение UILABEL и убедиться, что он устанавливается и GT; = 0, как показано на рисунке ниже. Введите описание изображения здесь

 

What I did in my app was to set the UILabel's line property to 0 as well as to create a bottom constraint of the UILabel and make sure it is being set to >= 0 as shown in the image below. enter image description here

</div
 
 
 
 
20
 
vote

Я взял предложения здесь и создал представление, которое может обернуть UILabel и разместить его и установить количество строк, чтобы он был выровнен наверху. Просто поместите 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   
 

I took the suggestions here and created a view which can wrap a UILabel and will size it and set the number of lines so that it is top aligned. Simply put a UILabel as a subview:

@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 
</div
 
 
20
 
vote

Вы можете использовать tttattribedlabel , он поддерживает вертикальное выравнивание.

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

You can use TTTAttributedLabel, it supports vertical alignment.

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

Я нашел ответы на этот вопрос теперь немного устарел, поэтому добавляя это для любителей автоматического макета там.

Автомаклат делает эту проблему довольно тривиально. Предполагая, что мы добавляем этикетку в <код> 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 . < / P >.

 

I've found the answers on this question are now a bit out-of-date, so adding this for the auto layout fans out there.

Auto layout makes this issue pretty trivial. Assuming we're adding the label to UIView *view, the following code will accomplish this:

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

The label's height will be calculated automatically (using it's intrinsicContentSize) and the label will be positioned edge-to-edge horizontally, at the top of the view.

</div
 
 
16
 
vote

Я использовал много способов выше, и просто хочу добавить быстрый и грязный подход, который я использовал:

 <код> myLabel.text = [NSString stringWithFormat:@"%@         ",@"My label text string"];   

Убедитесь, что количество новых линий в строке приведет к тому, что любой текст наполняет доступное вертикальное пространство и установить UILabel для усечения любого переполненного текста.

потому что иногда достаточно хорошее, это достаточно хорошо .

 

I've used a lot of the methods above, and just want to add a quick-and-dirty approach I've used:

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

Make sure the number of newlines in the string will cause any text to fill the available vertical space, and set the UILabel to truncate any overflowing text.

Because sometimes good enough is good enough.

</div
 
 
         
         
16
 
vote

Используйте <код> textRect(forBounds:limitedToNumberOfLines:) .

 <код> class TopAlignedLabel: UILabel {   override func drawText(in rect: CGRect) {     let textRect = super.textRect(forBounds: bounds, limitedToNumberOfLines: numberOfLines)     super.drawText(in: textRect)   } }   
 

Use textRect(forBounds:limitedToNumberOfLines:).

class TopAlignedLabel: UILabel {   override func drawText(in rect: CGRect) {     let textRect = super.textRect(forBounds: bounds, limitedToNumberOfLines: numberOfLines)     super.drawText(in: textRect)   } } 
</div
 
 
         
         
14
 
vote

Я хотел иметь метку, которая смогла иметь многонаправочные, минимальный размер шрифта и центрировал как горизонтально, так и вертикально в его родительском представлении. Я добавил свой ярлык программно на мой взгляд:

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

Надеюсь, что поможет кому-то!

 

I wanted to have a label which was able to have multi-lines, a minimum font size, and centred both horizontally and vertically in it's parent view. I added my label programmatically to my 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]; } 

And then when I wanted to change the text of my 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]; } 

Hope that helps someone!

</div
 
 
14
 
vote

fxlabel (на github) выходит из коробки, установив <код> label.contentMode к <код> UIViewContentModeTop . Этот компонент не сделан мной, но это компонент, который я часто использую и имеет тонны функций, и, кажется, хорошо работает.

 

FXLabel (on github) does this out of the box by setting label.contentMode to UIViewContentModeTop. This component is not made by me, but it is a component I use frequently and has tons of features, and seems to work well.

</div
 
 
11
 
vote

Для тех, кто читал это, потому что текст внутри вашей этикетки не вертикально в центре, имею в виду, что некоторые типы шрифтов не предназначены одинаково. Например, если вы создаете метку с размером 16 Zapfino, вы увидите, что текст не идеально сосредоточен вертикально.

Тем не менее, работа с Helvetica будет вертикально центрировать ваш текст.

 

for anyone reading this because the text inside your label is not vertically centered, keep in mind that some font types are not designed equally. for example, if you create a label with zapfino size 16, you will see the text is not perfectly centered vertically.

however, working with helvetica will vertically center your text.

</div
 
 
 
 
10
 
vote

Подкласс UILabel и ограничить рисунок прямоугольник, как это:

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

Я попробовал решение с участием новой прокладки и бегал в неверное поведение в некоторых случаях. По моему опыту легче ограничить рисунок прямоу, как прежде чем беспорядок <код> numberOfLines .

P.S. Вы можете себе представить, легко поддерживать 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]; }   
 

Subclass UILabel and constrain the drawing rectangle, like this:

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

I tried the solution involving newline padding and ran into incorrect behavior in some cases. In my experience, it's easier to constrain the drawing rect as above than mess with numberOfLines.

P.S. You can imagine easily supporting UIViewContentMode this way:

- (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]; } 
</div
 
 
10
 
vote

Если вы используете Autolayout, установите вертикальную ContentHuggingPriority до 1000, либо в коде, либо в IB. В IB вам может придеться удалить ограничение высоты, установив приоритет к 1, а затем удалять его.

 

If you are using autolayout, set the vertical contentHuggingPriority to 1000, either in code or IB. In IB you may then have to remove a height constraint by setting it's priority to 1 and then deleting it.

</div
 
 
8
 
vote

до тех пор, пока вы не выполняете сложную задачу, вы можете использовать <код> UITextView вместо <код> class TopAlignedLabel: UILabel { override func drawText(in rect: CGRect) { let textRect = super.textRect(forBounds: bounds, limitedToNumberOfLines: numberOfLines) super.drawText(in: textRect) } } 0 .

Отключить свиток.

Если вы хотите, чтобы текст отображался полностью просто пользователя <код> class TopAlignedLabel: UILabel { override func drawText(in rect: CGRect) { let textRect = super.textRect(forBounds: bounds, limitedToNumberOfLines: numberOfLines) super.drawText(in: textRect) } } 1 и <код> class TopAlignedLabel: UILabel { override func drawText(in rect: CGRect) { let textRect = super.textRect(forBounds: bounds, limitedToNumberOfLines: numberOfLines) super.drawText(in: textRect) } } 2 методы

 

As long as you are not doing any complex task, you can use UITextView instead of UILabels.

Disable the scroll.

If you want the text to be displayed completely just user sizeToFit and sizeThatFits: methods

</div
 
 
8
 
vote

в Swift,

<Код> class TopAlignedLabel: UILabel { override func drawText(in rect: CGRect) { let textRect = super.textRect(forBounds: bounds, limitedToNumberOfLines: numberOfLines) super.drawText(in: textRect) } } 3

Чтобы сделать ваш текст своей метки, чтобы соответствовать экрану, и он на вершине

<Код> class TopAlignedLabel: UILabel { override func drawText(in rect: CGRect) { let textRect = super.textRect(forBounds: bounds, limitedToNumberOfLines: numberOfLines) super.drawText(in: textRect) } } 4

Чтобы сделать ваш шрифт метки, чтобы соответствовать ширине экрана или определенного размера ширины.

<Код> class TopAlignedLabel: UILabel { override func drawText(in rect: CGRect) { let textRect = super.textRect(forBounds: bounds, limitedToNumberOfLines: numberOfLines) super.drawText(in: textRect) } } 5

и некоторое текстовое устройство для метки:

<Код> class TopAlignedLabel: UILabel { override func drawText(in rect: CGRect) { let textRect = super.textRect(forBounds: bounds, limitedToNumberOfLines: numberOfLines) super.drawText(in: textRect) } } 6

<Код> class TopAlignedLabel: UILabel { override func drawText(in rect: CGRect) { let textRect = super.textRect(forBounds: bounds, limitedToNumberOfLines: numberOfLines) super.drawText(in: textRect) } } 7

<Код> class TopAlignedLabel: UILabel { override func drawText(in rect: CGRect) { let textRect = super.textRect(forBounds: bounds, limitedToNumberOfLines: numberOfLines) super.drawText(in: textRect) } } 8

<Код> class TopAlignedLabel: UILabel { override func drawText(in rect: CGRect) { let textRect = super.textRect(forBounds: bounds, limitedToNumberOfLines: numberOfLines) super.drawText(in: textRect) } } 9

<Код> - (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]; } 0

 

In swift,

let myLabel : UILabel!

To make your text of your Label to fit to screen and it's on the top

myLabel.sizeToFit()

To make your font of label to fit to the width of screen or specific width size.

myLabel.adjustsFontSizeToFitWidth = YES

and some textAlignment for label :

myLabel.textAlignment = .center

myLabel.textAlignment = .left

myLabel.textAlignment = .right

myLabel.textAlignment = .Natural

myLabel.textAlignment = .Justified

</div
 
 
 
 
7
 
vote

Это старое решение, используйте автолаю на iOS & GT; = 6

Мое решение:

  1. Разделить линии самостоятельно (игнорирование настроек завершения этикеток)
  2. нарисовать линии самостоятельно (игнорируя выравнивание метки)
 <код> - (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]; } 1  
 <код> - (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]; } 2  
 

This is an old solution, use the autolayout on iOS >= 6

My solution:

  1. Split lines by myself (ignoring label wrap settings)
  2. Draw lines by myself (ignoring label 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 
</div
 
 

Связанный проблема

0  Realm.io Array Создание  ( Realm io array creation ) 
Какой правильный способ создать rlmobject с массивом других rlmobjects? Документы ничего не упоминают и мои первоначальные попытки (ничего не делайте, предп...

1  Есть ли способ использовать координаты для выбора элемента в автоматизации тестирования IOS UI?  ( Is there a way to use coordinates to select an element in ios ui test automation ) 
Я имею дело с <код> UICollectionView , который имеет много элементов. Один из них, это <код> UISuplementaryView , который содержит множество кликабельных ячее...

2  Мое обновление приложения iOS удаляет постоянные данные из старой версии пользователей  ( My ios app update deletes persistent data from users older version ) 
В моем приложении iOS я разрешу пользователя сохранить свои пресеты пользовательского интерфейса. <код> public interface ITestServiceCallback { [Operati...

-1  Переместите анимированный символ только в то время как кнопка удерживается  ( Move an animated character only while a button is held down ) 
Я пытался сделать накрасочный персонаж двигаться с четырьмя стрелками: вверх, прямо, левый и вниз, как игровая мальчик. Я сделал это: <код> - (IBActio...

0  Падение на хранение текущего пользователя в основных данных  ( Falling to store current user in core data ) 
Что-то действительно странное происходит с моим кодом, и я не знаю, как это исправить. Когда я хочу хранить некоторые пользователи в основных данных, он работ...

2  IOS: Как нарисовать линию между двумя движущимися объектами?  ( Ios how to draw a line between two moving objects ) 
Я в основном имеющую массив объектов UIView, которые находятся на экране. Они перемещаются случайным образом вокруг, и я хотел бы иметь строку, соединяющую ка...

46  Как проверить push-уведомление работает в моем приложении  ( How to test push notification is working in my application ) 
В моем приложении я реализую службу Push-уведомления. У меня есть сервер поставщика контента, который содержит некоторые продукты в нем. Я создал сертификат...

2  Wkwebview: возможно ли предварительно загрузить несколько URL?  ( Wkwebview is it possible to preload multiple urls ) 
Просто мигрировал приложение на <код> WKWebView и был заданным вопросом, есть ли возможным способом «предварительно загрузить несколько URL-адресов, но тольк...

1  Обновление NsmanageObjects на заднем плане  ( Updating nsmanagedobjects in the background ) 
Я пытаюсь обновить NSManagedObject в фоновом режиме на основе свойств из сети сети. Возникли проблемы с обертыванием моей головы вокруг параллелизма. То, что ...

0  Симулятор iPad показывает черный экран слева?  ( Ipad simulator showing black screen on the left ) 
Привет, я делаю приложение iPhone / iPad. Однако в симуляторе iPad экран показывает черный экран слева без видимых причин. Я запустил приложение с симулято...

32  В чем разница между ns_enum и ns_options?  ( What is the difference between ns enum and ns options ) 
i предварительно назначил следующий код с помощью clang в xcode5. <код> typedef NS_ENUM(NSInteger, MyStyle) { MyStyleDefault, MyStyleCustom }; type...

-1  Могу ли я использовать PHP без протокола веб-службы стиля отдыха для создания сервера пропуска? [закрыто]  ( Can i use php without rest style web service protocol to create server of pass ) 
<в сторону CLASS = "S-NEWACTS S-WELTIVE__info JS-Post-New Imide MB16« Роль = «Статус»> <Путь d = "M15 6.38A6.48 6.48 0 007.78. 04H-.02A6.49 6.49 0 002.05 ...

0  Уволить контроллер просмотра, когда он был назван «PerforgeGege»?  ( Dismiss view controller when it was called by performsegue ) 
У меня есть три контроллера просмотра: <код> Main , <код> VC1 , а <код> VC2 . Всякий раз, когда приложение запускает метод делегата определяет, какой VC будет...

15  Получение новейших уведомлений только тогда, когда приложение работает  ( Receiving newsstand notifications only when app is running ) 
Я не получаю уведомления в газете, когда приложение не работает, вот что я сделал. Приложение имеет правильные клавиши Plist 'uinewsstancstApp = yes and' ui...

0  «NsconcretemutableAttribedString initwithString) :: Nil Value 'при использовании Google рядом с сообщениями  ( Nsconcretemutableattributedstring initwithstring nil value when using google ) 
Я следовал в документации Google для использования API BearmyBymessages. Я использую Swift3. У меня есть следующий код, чтобы настроить приложение для публика...

Связанный проблема

0  Realm.io Array Создание 
1  Есть ли способ использовать координаты для выбора элемента в автоматизации тестирования IOS UI? 
2  Мое обновление приложения iOS удаляет постоянные данные из старой версии пользователей 
-1  Переместите анимированный символ только в то время как кнопка удерживается 
0  Падение на хранение текущего пользователя в основных данных 
2  IOS: Как нарисовать линию между двумя движущимися объектами? 
46  Как проверить push-уведомление работает в моем приложении 
2  Wkwebview: возможно ли предварительно загрузить несколько URL? 
1  Обновление NsmanageObjects на заднем плане 
0  Симулятор iPad показывает черный экран слева? 
32  В чем разница между ns_enum и ns_options? 
-1  Могу ли я использовать PHP без протокола веб-службы стиля отдыха для создания сервера пропуска? [закрыто] 
0  Уволить контроллер просмотра, когда он был назван «PerforgeGege»? 
15  Получение новейших уведомлений только тогда, когда приложение работает 
0  «NsconcretemutableAttribedString initwithString) :: Nil Value 'при использовании Google рядом с сообщениями