UILabel - мітка автоматичного розміру, щоб відповідати тексту?


144

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

Отже, якщо користувач вводить "привіт" або "моє ім'я дійсно довге, я хочу, щоб воно вмістилося в цю скриньку", воно ніколи не буде усічено, а мітка відповідно "розширена"?


Будь-хто, будь ласка, допоможіть мені у наданні швидких кодів ..
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
Karan Alangat

1
UILabel не змінює розмір себе, коли тексту менше / більше. я використовую автоматичне розташування. Спробував зробити UILabel, але вони створюються щоразу, коли ініціалізується клітинкаForRowAtIndex. Перепробував багато речей. Нічого не працює для мене. Фон uilabel приймає однакову ширину. ДОПОМОГА !!!
coreDeviOS

@Daniel Я встановив кількість рядків = 0, але його не працює. Я встановив обмеження по горизонталі та вертикалі по центру. Ще одне, що я зробив, - це скласти підклас UILABEL і використовувати його для цієї мітки
Jasmeet

За допомогою автоматичного вимикання найпростіше рішення: (1) Встановіть рядки на 0, (2) Встановіть обмеження ширини на "Більше або рівне" з постійним 0, (3) Встановіть обмеження по висоті на "Більше, ніж рівне" з постійним 0, ( 4) Вирівняйте так, як зазвичай, наприклад, по центру по горизонталі та вертикалі.
Ерік ван дер Нойт

76

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

Хоча я рекомендую використовувати авторозмітку і дозволити мітці змінити розмір себе на основі обмежень.


3
Під час використання swift мені довелося запустити це на головній нитці за допомогою dispatch_async (dispatch_get_main_queue (), {});
Zeezer

@Zeezer ти знаєш чому?
FurloSK

13
@FurloSK Будь-які зміни в інтерфейсі повинні бути виконані в основному потоці.
Гільгерме Торрес Кастро

32

Якщо ми хочемо, щоб UILabelце зменшилось і розширилося на основі розміру тексту, тоді найкраща опція - розгортка із автоматичним розкладом. Нижче наведено кроки для досягнення цього

Кроки

  1. Поставте UILabel у контролер перегляду та поставте його куди завгодно. Також здано 0у numberOfLinesвласність UILabel.

  2. Надайте їй обмеження на верхньому, провідному та нижньому просторі.

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

  1. Тепер він дасть попередження, Натисніть на жовту стрілку.

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

  1. Клацніть Update Frameі натисніть на Fix Misplacement. Тепер цей UILabel зменшиться, якщо тексту менше, і розшириться, якщо тексту більше.

1
Я не перевіряв локалізацію, але це теж має працювати.
Йогеш Сутар

2
Я не міг змусити це працювати з існуючим проектом, поки я не зняв прапорець "Краща ширина" "Явний", і все це спрацювало нормально.
zorro2b

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"
        }
    }
  • Якщо ви хочете, щоб ваш ярлик обернув рядок, тоді встановіть кількість рядків 0 в IB та додайте myLabel.preferredMaxLayoutWidth = 150 // or whateverкод. (Я також прив’язав свою кнопку до нижньої частини етикетки, щоб вона рухалася вниз, коли висота мітки зростала.)

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

  • Якщо ви шукаєте динамічні розміри міток всередині, UITableViewCellто дивіться цю відповідь .

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


Привіт, я отримав розмір мітки, але я не розумію, як змінити висоту комірки. Чи можете ви, будь ласка, дайте мені знати, як змінити розмір комірки.
Вівек

@Vivek, якщо у вас немає обмежень по висоті, він повинен змінювати розмір автоматично.
Сурагч

Так, але як це можливо, коли я використовую власну клітинку, і я поміщаю 2 мітки в його клітинку.
Вівек

@Vivek, вибачте, я неправильно прочитав ваше запитання. Ви вже отримали одну етикетку для роботи, переглянувши цю відповідь ?
Сурагч


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 за допомогою автоматичного вимикання. Ширина фіксована. 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. Ref Виведіть UILabel на Controller.h з id: label
  4. Controller.m та додай [label sizeToFit];у viewDidLoad

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

0

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

[self.yourLableName sizeToFit];

-1

Існує також такий підхід:

[self.myLabel changeTextWithAutoHeight:self.myStringToAssignToLabel width:180.0f];

Не я спротив цю відповідь, а я просто хотів зазначити, що я не можу побачити changeTextWithAutoHeight:width:метод UILabel. Чи можете ви надати посилання, будь ласка, на те, де в документації UIKit можна знайти цей метод.
Аділ
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.