Вертикально выравнивать текст вверху в UILabel
У меня есть UILabel
с пространством для двух строк текста. Иногда, когда текст слишком короткий, этот текст отображается в вертикальном центре метки.
Как вертикально выровнять текст всегда в верхней части UILabel
?
Ответы
Ответ 1
Там нет никакого способа установить вертикальное выравнивание на UILabel
, но вы можете получить тот же эффект, изменив рамку метки. Я сделал свои ярлыки оранжевыми, чтобы вы могли четко видеть, что происходит.
Вот быстрый и простой способ сделать это:
[myLabel sizeToFit];
Если у вас есть метка с более длинным текстом, который будет занимать более одной строки, установите для numberOfLines
значение 0
(ноль здесь означает неограниченное количество строк).
myLabel.numberOfLines = 0;
[myLabel sizeToFit];
Более длинная версия
Я сделаю свою метку в коде, чтобы вы могли видеть, что происходит. Вы можете настроить большую часть этого в Интерфейсном Разработчике также. Моя установка представляет собой приложение на основе вида с фоновым изображением, которое я сделал в 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
вступают в игру с center- или текстом, выровненным по правому краю. Вот что происходит:
// myLabel.textAlignment = NSTextAlignmentRight;
myLabel.textAlignment = NSTextAlignmentCenter;
[myLabel setNumberOfLines:0];
[myLabel sizeToFit];
Ярлык по-прежнему имеет фиксированный верхний левый angular. Вы можете сохранить исходную ширину метки в переменной и установить ее после sizeToFit
или задать фиксированную ширину, чтобы противостоять этим проблемам:
myLabel.textAlignment = NSTextAlignmentCenter;
[myLabel setNumberOfLines:0];
[myLabel sizeToFit];
CGRect myFrame = myLabel.frame;
// Resize the frame 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
работает как обычно. Ширина рамки все еще сужена, чтобы соответствовать самой правой букве.
Марк Эмери дал исправление для NIB и раскадровок, используя Auto Layout в комментариях:
Если ваша метка включена в перо или раскадровку в качестве подпредставления view
ViewController, который использует autolayout, то помещение вашего вызова sizeToFit
в viewDidLoad
не будет работать, потому что размеры autoolayout и расположение подпредставлений после viewDidLoad
вызывается и немедленно отменяет эффекты вашего вызова sizeToFit
. Однако вызов sizeToFit
из viewDidLayoutSubviews
будет работать.
Мой оригинальный ответ (для потомков/справок):
При этом используется метод 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;
Ответ 2
Установите новый текст:
myLabel.text = @"Some Text"
Установите maximum number
строк в 0 (автоматически):
myLabel.numberOfLines = 0
Установите максимальный размер рамки этикетки:
myLabel.frame = CGRectMake(20,20,200,800)
Вызовите sizeToFit
, чтобы уменьшить размер кадра, чтобы содержимое точно подходило:
[myLabel sizeToFit]
Рамка для надписей теперь достаточно высокая и достаточно широкая, чтобы вместить ваш текст. Верхний левый должен быть неизменным. Я проверял это только с выравниванием по верхнему левому краю текста. Для других выравниваний вам, возможно, придется изменить кадр позже.
Кроме того, на моем ярлыке включена перенос слов.
Ответ 3
Ссылаясь на решение для расширения:
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 также должен быть обновлен с помощью @" \[email protected]%"
вместо "\[email protected]%"
(для инициализации цикла необходимо заменить на "for (int я = 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.
Ответ 4
На всякий случай, если бы это помогало кому-либо, у меня была такая же проблема, но я смог решить проблему, просто переключившись с UILabel
на UITextView
. Я понимаю, что это не для всех, потому что функциональность немного отличается.
Если вы переключитесь на использование UITextView
, вы можете отключить все свойства просмотра прокрутки, а также включенное взаимодействие с пользователем... Это заставит его действовать как ярлык.
Ответ 5
Нет суеты, нет суеты
@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, нет суеты, кроме 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)
}
}
Ответ 6
Как и в предыдущем ответе, но это было не совсем правильно или легко похлопать по коду, поэтому я немного почистил его. Добавьте это расширение либо к своему собственному файлу .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];
Ответ 7
Еще более быстрый (и более грязный) способ выполнить это, установив режим разрыва строки UILabel на "Clip" и добавив фиксированное количество строк новой строки.
myLabel.lineBreakMode = UILineBreakModeClip;
myLabel.text = [displayString stringByAppendingString:"\n\n\n\n"];
Это решение не будет работать для всех - в частности, если вы все еще хотите показать "..." в конце строки, если она превышает количество строк, которые вы показываете, вам нужно будет используйте один из более длинных битов кода, но для многих случаев это даст вам то, что вам нужно.
Ответ 8
Вместо UILabel
вы можете использовать UITextField
, у которого есть опция вертикального выравнивания:
textField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
textField.userInteractionEnabled = NO; // Don't allow interaction
Ответ 9
Решение раскадровки: самым простым и простым способом является встраивание Label
в StackView
и установка Axis
StackView в Horizontal
, Alignment
до Top
в Attribute Inspector
из раскадровки.
Ответ 10
Я долгое время боролся с этим, и я хотел поделиться своим решением.
Это даст вам UILabel
, который будет автоматически печатать текст до 0,5 шкалы и вертикально центрировать текст. Эти параметры также доступны в Storyboard/IB.
[labelObject setMinimumScaleFactor:0.5];
[labelObject setBaselineAdjustment:UIBaselineAdjustmentAlignCenters];
Ответ 11
Создайте новый класс
LabelTopAlign
.h файл
#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
Изменить
Здесь выполняется более простая реализация, которая делает то же самое:
#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
Ответ 12
В интерфейсе Builder
- Установите
UILabel
размер максимально возможного текста
- Установите
Lines
в '0' в Инспекторе атрибутов
В вашем коде
- Установите текст метки
- Вызов
sizeToFit
на вашей этикетке
Фрагмент кода:
self.myLabel.text = @"Short Title";
[self.myLabel sizeToFit];
Ответ 13
Для Adaptive UI (iOS8 или после) вертикальное выравнивание UILabel должно быть установлено из StoryBoard путем изменения свойств
noOfLines
= 0` и
Ограничения
-
Корректировка ограничений UILabel LefMargin, RightMargin и Top Margin.
-
Измените Content Compression Resistance Priority For Vertical
= 1000` Чтобы вертикальный > горизонтальный.
Отредактировано:
noOfLines=0
и для достижения желаемых результатов достаточно следующих ограничений.
Ответ 14
Создайте подкласс UILabel. Работает как шарм:
// 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
Как обсуждалось здесь.
Ответ 15
Я написал функцию утилиты для достижения этой цели. Вы можете посмотреть:
// 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;
}
.Как использовать? (Если 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
Ответ 16
Мне потребовалось некоторое время, чтобы прочитать код, а также код на введенной странице и обнаружили, что все они пытаются изменить размер фрейма метки, так что центральное вертикальное выравнивание по умолчанию не появится.
Однако в некоторых случаях мы хотим, чтобы метка занимала все эти пробелы, даже если метка имеет столько текста (например, несколько строк с одинаковой высотой).
Здесь я использовал альтернативный способ его решения, просто добавив новые строки в конец метки (обратите внимание, что я действительно унаследовал 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 "];
}
Ответ 17
Я воспользовался этими предложениями и создал представление, которое может обернуть 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
Ответ 18
Вы можете использовать TTTAttributedLabel, он поддерживает вертикальное выравнивание.
@property (nonatomic) TTTAttributedLabel* label;
<...>
//view or viewController init method
_label.verticalAlignment = TTTAttributedLabelVerticalAlignmentTop;
Ответ 19
Я использовал много методов выше и просто хочу добавить быстрый и грязный подход, который я использовал:
myLabel.text = [NSString stringWithFormat:@"%@\n\n\n\n\n\n\n\n\n",@"My label text string"];
Убедитесь, что количество строк в строке приведет к тому, что любой текст заполнит доступное вертикальное пространство и установите UILabel для обрезания любого переполняющего текста.
Потому что иногда достаточно хорошо.
Ответ 20
Я нашел ответы на этот вопрос в настоящее время немного устаревшими, поэтому добавив это для поклонников автомакетов там.
Автоматическая компоновка делает эту проблему довольно тривиальной. Предполагая, что мы добавляем метку к 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
.
Ответ 21
В моем приложении я установил для свойства линии UILabel значение 0, а также для создания нижнего ограничения UILabel и убедитесь, что для него установлено значение> = 0, как показано на рисунке ниже.
Ответ 22
Я хотел иметь метку, которая могла бы иметь многострочные линии, минимальный размер шрифта и центрироваться как по горизонтали, так и по вертикали в своем родительском представлении. Я добавил программный код на мой взгляд:
- (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 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];
}
Надеюсь, что это поможет кому-то!
Ответ 23
FXLabel (на github) делает это из коробки, устанавливая label.contentMode
на UIViewContentModeTop
. Этот компонент не сделан мной, но это компонент, который я часто использую и имеет множество функций, и, похоже, работает хорошо.
Ответ 24
для всех, кто читает это, потому что текст внутри вашей метки не имеет вертикальной ориентации, помните, что некоторые типы шрифтов не разработаны одинаково. например, если вы создаете метку с размером zapfino 16, вы увидите, что текст не идеально по вертикали.
однако работа с helvetica будет вертикально центрировать ваш текст.
Ответ 25
Подкласс 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];
}
Ответ 26
Если вы используете автозапуск, установите вертикальный контентHuggingPriority 1000, либо в коде, либо в IB. В IB вам может потребоваться удалить ограничение по высоте, установив приоритет на 1, а затем удалив его.
Ответ 27
Используйте textRect(forBounds:limitedToNumberOfLines:)
.
class TopAlignedLabel: UILabel {
override func drawText(in rect: CGRect) {
let textRect = super.textRect(forBounds: bounds, limitedToNumberOfLines: numberOfLines)
super.drawText(in: textRect)
}
}
Ответ 28
Пока вы не выполняете сложную задачу, вы можете использовать UITextView
вместо UILabels
.
Отключить прокрутку.
Если вы хотите, чтобы текст отображался полностью как пользовательские методы sizeToFit
и sizeThatFits:
Ответ 29
В быстром,
let myLabel : UILabel!
Чтобы текст вашего ярлыка соответствовал экрану, а он сверху
myLabel.sizeToFit()
Чтобы ваш шрифт метки соответствовал ширине экрана или определенному размеру ширины.
myLabel.adjustsFontSizeToFitWidth = YES
и некоторая textAlignment для метки:
myLabel.textAlignment = .center
myLabel.textAlignment = .left
myLabel.textAlignment = .right
myLabel.textAlignment = .Natural
myLabel.textAlignment = .Justified
Ответ 30
Это старое решение, используйте автоматическое расположение на iOS> = 6
Мое решение:
- Разделить линии самостоятельно (игнорируя настройки переноса меток)
- Нарисуйте линии самостоятельно (игнорируя выравнивание надписей)
@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