UILabel - метка авторазмера под текст?

144

Можно ли автоматически изменить размер поля / границ UILabel, чтобы оно соответствовало содержанию текста? (Мне все равно, если он окажется больше, чем дисплей)

Так что, если пользователь вводит «привет» или «мое имя действительно длинное, я хочу, чтобы оно вписывалось в это поле», оно никогда не будет усечено, а метка соответственно «расширена»?

wayneh
источник
Кто-нибудь, пожалуйста, помогите мне с предоставлением быстрых кодов ..
Angel F Syrus

Ответы:

98

Пожалуйста, проверьте мою суть, где я сделал категорию для UILabelчего-то очень похожего, моя категория позволяет UILabelрастянуть ее высоту, чтобы показать весь контент: https://gist.github.com/1005520

Или проверить этот пост: https://stackoverflow.com/a/7242981/662605

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

@implementation UILabel (dynamicSizeMeWidth)

- (void)resizeToStretch{
    float width = [self expectedWidth];
    CGRect newFrame = [self frame];
    newFrame.size.width = width;
    [self setFrame:newFrame];
}

- (float)expectedWidth{
    [self setNumberOfLines:1];

    CGSize maximumLabelSize = CGSizeMake(CGRectGetWidth(self.bounds), CGFLOAT_MAX);

    CGSize expectedLabelSize = [[self text] sizeWithFont:[self font] 
                                            constrainedToSize:maximumLabelSize
                                            lineBreakMode:[self lineBreakMode]]; 
    return expectedLabelSize.width;
}

@end

Вы можете более просто использовать sizeToFitметод, доступный в UIViewклассе, но установить количество строк равным 1, чтобы быть безопасным.


обновление iOS 6

Если вы используете AutoLayout, то у вас есть встроенное решение. Установив количество строк равным 0, каркас будет соответствующим образом изменять размер вашей метки (добавляя больше высоты), чтобы соответствовать вашему тексту.


обновление iOS 8

sizeWithFont:устарела, поэтому используйте sizeWithAttributes:вместо:

- (float)expectedWidth{
    [self setNumberOfLines:1];

    CGSize expectedLabelSize = [[self text] sizeWithAttributes:@{NSFontAttributeName:self.font}];

    return expectedLabelSize.width;
}
Даниил
источник
8
Используя метод iOS 6 AutoLayout, я получил ограничение по высоте на ярлыке, от которого я не смог избавиться. Установка отношения ограничения высоты на «Больше или равно» позволила высоте расти.
Майкл Лутон
2
sizeWithFont: constrainedToSize: lineBreakMode: метод запрещен в ios 7
Каран Алангат
1
UILabel не меняет размер, когда текст меньше / больше. Я использую Авто-макет. Пробовал делать UILabel, но они создаются каждый раз при инициализации cellForRowAtIndex. Перепробовал много вещей. Ничего не работает для меня. Фон уилабеля принимают одинаковой ширины. Помогите !!!
coreDeviOS
@Daniel Я установил количество строк = 0, но это не работает. Я установил ограничения по горизонтали и вертикали центра. Еще одна вещь, которую я сделал, - это создание подкласса UILABEL и использование его для этого ярлыка
Jasmeet
С Autolayout самое простое решение: (1) установить линии на 0, (2) установить ограничение ширины на «больше или равно» с константой 0, (3) установить ограничение высоты на «больше или равно» с константой 0, ( 4) Выровняйте, как обычно, например, центрируя по горизонтали и вертикали.
Эрик ван дер
76

Использование [label sizeToFit];достигнет того же результата из категории Daniels.

Хотя я рекомендую использовать autolayout и позволить метке самому изменяться в зависимости от ограничений.

Гильерме Торрес Кастро
источник
3
При использовании swift мне пришлось запустить это в главном потоке, используя dispatch_async (dispatch_get_main_queue (), {});
Zeezer
@Zeezer ты знаешь почему?
FurloSK
13
@FurloSK Любые изменения в пользовательском интерфейсе должны быть сделаны в главном потоке.
Гильерме Торрес Кастро
32

Если мы этого хотим UILabel уменьшалось и расширялось в зависимости от размера текста, тогда раскадровка с автопоставкой является лучшим вариантом. Ниже приведены шаги для достижения этой цели.

меры

  1. Поместите UILabel в поле зрения контроллера и разместите его там, где вы хотите. Также положить 0на numberOfLinesимущество UILabel.

  2. Дайте ему ограничение Top, Leading и Trailing space.

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

  1. Теперь он выдаст предупреждение. Нажмите на желтую стрелку.

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

  1. Нажмите Update Frameи нажмите Fix Misplacement. Теперь эта UILabel будет уменьшаться, если текст меньше, и расширяется, если текст больше.
Йогеш Сутар
источник
1
Я не проверял на локализацию, но она должна работать и для этого.
Йогеш Сутар
2
Я не мог заставить это работать с существующим проектом, пока я не снял флажок «Предпочитаемая ширина» «Явный», тогда все работало нормально.
zorro2b 22.09.16
25

Это не так сложно, как делают некоторые другие ответы.

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

Прикрепите левый и верхний края

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

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

После этого он автоматически изменит размер.

Ноты

  • Не добавляйте ограничения для ширины и высоты. Ярлыки имеют собственный размер в зависимости от их текстового содержимого.
  • Спасибо за этот ответ за помощь с этим.
  • Не нужно устанавливать sizeToFitпри использовании автоматического макета. Мой полный код для примера проекта здесь:

    import UIKit
    class ViewController: UIViewController {
    
        @IBOutlet weak var myLabel: UILabel!
    
        @IBAction func changeTextButtonTapped(sender: UIButton) {
            myLabel.text = "my name is really long i want it to fit in this box"
        }
    }
  • Если вы хотите, чтобы ваша метка была переносом строк, установите число строк в IB в 0 и добавьте myLabel.preferredMaxLayoutWidth = 150 // or whateverкод. (Я также прикрепил кнопку к нижней части этикетки, чтобы она могла двигаться вниз при увеличении высоты этикетки.)

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

  • Если вы ищете динамически изменяемые размеры меток внутри, UITableViewCellпосмотрите этот ответ .

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

Suragch
источник
Привет, я получил ярлык с измененным размером, но я не понимаю, как изменить размер ячейки. Пожалуйста, дайте мне знать, как изменить высоту ячейки.
Вивек
@Vivek, если у вас нет ограничений на высоту, размер должен изменяться автоматически.
Сурагч
Да, но как это возможно, когда я использую пользовательскую ячейку и помещаю 2 ярлыка в его ячейку.
Вивек
@ Вивек, извини, я неправильно понял твой вопрос. Вы уже заставили работать один ярлык, пройдя этот ответ ?
Сурагч
9

Используйте [label sizeToFit];для настройки текста в UILabel

Гаурав Гилани
источник
5

Я создал несколько методов, основанных на ответе Даниила выше.

-(CGFloat)heightForLabel:(UILabel *)label withText:(NSString *)text
{
    CGSize maximumLabelSize     = CGSizeMake(290, FLT_MAX);

    CGSize expectedLabelSize    = [text sizeWithFont:label.font
                                constrainedToSize:maximumLabelSize
                                    lineBreakMode:label.lineBreakMode];

    return expectedLabelSize.height;
}

-(void)resizeHeightToFitForLabel:(UILabel *)label
{
    CGRect newFrame         = label.frame;
    newFrame.size.height    = [self heightForLabel:label withText:label.text];
    label.frame             = newFrame;
}

-(void)resizeHeightToFitForLabel:(UILabel *)label withText:(NSString *)text
{
    label.text              = text;
    [self resizeHeightToFitForLabel:label];
}
Даг Бейкер
источник
5

Вот что я нахожу работы для моей ситуации:

1) Высота UILabel имеет ограничение> = 0, используя autolayout. Ширина фиксирована. 2) Присвойте текст в UILabel, у которого уже есть супервизия (не уверен, насколько это важно). 3) Затем выполните:

    label.sizeToFit()
    label.layoutIfNeeded()

Высота метки теперь установлена ​​соответствующим образом.

Крис Принс
источник
3
@implementation UILabel (UILabel_Auto)

- (void)adjustHeight {

    if (self.text == nil) {
        self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.bounds.size.width, 0);
        return;
    }

    CGSize aSize = self.bounds.size;
    CGSize tmpSize = CGRectInfinite.size;
    tmpSize.width = aSize.width;

    tmpSize = [self.text sizeWithFont:self.font constrainedToSize:tmpSize];

    self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, aSize.width, tmpSize.height);
}

@end

Это метод категории. Вы должны сначала установить текст, а затем вызывать этот метод для настройки высоты UILabel.

Кайджай Лу
источник
2

Вы можете изменить размер этикетки в соответствии с текстом и другими связанными элементами управления двумя способами:

  1. Для iOS 7.0 и выше

    CGSize labelTextSize = [labelText boundingRectWithSize:CGSizeMake(labelsWidth, MAXFLOAT)
                                              options:NSStringDrawingUsesLineFragmentOrigin
                                           attributes:@{
                                                        NSFontAttributeName : labelFont
                                                        }
                                              context:nil].size;

до iOS 7.0 это можно было использовать для расчета размера этикетки

CGSize labelTextSize = [label.text sizeWithFont:label.font 
                            constrainedToSize:CGSizeMake(label.frame.size.width, MAXFLOAT)  
                                lineBreakMode:NSLineBreakByWordWrapping];

// переоснащаем другие элементы управления на основе labelTextHeight

CGFloat labelTextHeight = labelTextSize.height;
  1. Если вы не хотите вычислять размер текста надписи, вы можете использовать -sizeToFit в экземпляре UILabel as-

    [label setNumberOfLines:0]; // for multiline label
    [label setText:@"label text to set"];
    [label sizeToFit];// call this to fit size of the label according to text

// после этого вы можете получить рамку метки для перефразирования других связанных элементов управления

Вижееш
источник
2
  1. Добавьте недостающие ограничения в раскадровку.
  2. Выберите UILabel в раскадровке и установите атрибуты «Линия» на 0.
  3. Переведите UILabel в Controller.h с идентификатором: label
  4. Controller.m и добавь [label sizeToFit];в viewDidLoad
user2941395
источник
1

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

Недостающий ингредиент был нижним ограничением для описания.

Я изменил нижнее ограничение динамического элемента с = 0 на > = 0 .

Боян Тадич
источник
Это спасло мою жизнь. Если вы пытаетесь следовать: github.com/honghaoz/…, это правильный ответ.
Джастин Файлс,
0

Подходит каждый раз! :)

    name.text = @"Hi this the text I want to fit to"
    UIFont * font = 14.0f;
    CGSize size = [name.text sizeWithAttributes:@{NSFontAttributeName: font}];
    nameOfAssessment.frame = CGRectMake(400, 0, size.width, 44);
    nameOfAssessment.font = [UIFont systemFontOfSize:font];
HannahCarney
источник
0

Вы можете показать вывод одной строки, затем установить свойство Line = 0 и показать вывод нескольких строк, а затем установить свойство Line = 1 и более

[self.yourLableName sizeToFit];
Диксит Акабари
источник
-1

Есть также такой подход:

[self.myLabel changeTextWithAutoHeight:self.myStringToAssignToLabel width:180.0f];
Дейв Коул
источник
Это был не я, кто отклонил этот ответ, но я просто хотел указать, что я не могу увидеть changeTextWithAutoHeight:width:метод UILabel. Не могли бы вы предоставить ссылку, пожалуйста, где в документации UIKit этот метод можно найти.
Адиль Хуссейн