Выровнять текст по вертикали внутри UILabel - PullRequest
2098 голосов
/ 28 июня 2009

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

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

image representing a UILabel with vertically-centered text

Ответы [ 48 ]

42 голосов
/ 28 марта 2017

Раскадровка: Самый простой и легкий способ - встроить Label в StackView и установить для StackView Axis в Horizontal, Alignment в Top в Attribute Inspector из раскадровки.

enter image description here

38 голосов
/ 03 января 2012

enter image description here

В Интерфейсном Разработчике

  • Установить UILabel для размера максимально возможного текста
  • Установите Lines в '0' в Инспекторе Атрибутов

В вашем коде

  • Установить текст метки
  • Звоните sizeToFit на свой ярлык

Фрагмент кода:

self.myLabel.text = @"Short Title";
[self.myLabel sizeToFit];
34 голосов
/ 08 августа 2015

Для Adaptive UI (iOS8 или более поздняя версия) вертикальное выравнивание UILabel должно быть установлено из StoryBoard путем изменения свойств noOfLines = 0` и

Препятствия

  1. Настройка UILabel LefMargin, RightMargin и ограничений верхнего поля.

  2. Изменить Content Compression Resistance Priority For Vertical = 1000`, чтобы Вертикально> Горизонтально.

Constraints of UILabel

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

noOfLines=0

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

enter image description here

33 голосов
/ 14 июля 2011

Создать подкласс 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

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

27 голосов
/ 23 мая 2011

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

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

owКак использовать? (Если 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

26 голосов
/ 30 января 2010

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

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

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

Я взял здесь предложения и создал представление, которое может обернуть 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 голосов
/ 28 августа 2014

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

@property (nonatomic) TTTAttributedLabel* label;
<...>

//view's or viewController's init method
_label.verticalAlignment = TTTAttributedLabelVerticalAlignmentTop;
15 голосов
/ 18 сентября 2012

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

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

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

Потому что иногда достаточно хорошо достаточно хорошо .

14 голосов
/ 27 сентября 2013

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

...