Отрегулируйте высоту UILabel в зависимости от текста

Предположим, у меня есть следующий текст в UILabel (длинная строка динамического текста):

Since the alien army vastly outnumbers the team, players must use the post-apocalyptic world to their advantage, such as seeking cover behind dumpsters, pillars, cars, rubble, and other objects.

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

myUILabel.lineBreakMode = UILineBreakModeWordWrap;
myUILabel.numberOfLines = 0;

Пожалуйста, дайте мне знать, если я не иду в правильном направлении. Спасибо.

См. Также: stackoverflow.com/questions/406212/…

Richard Campbell 15.01.2009 21:35

Версия Swift внизу: stackoverflow.com/a/33945342/1634890

Juan Boero 26.11.2015 21:56
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
321
2
281 947
34
Перейти к ответу Данный вопрос помечен как решенный

Ответы 34

Вы можете реализовать метод TableViewController's(UITableViewCell *)tableView:cellForRowAtIndexPath следующим образом (например):

#define CELL_LABEL_TAG 1

- (UITableViewCell *)tableView:(UITableView *)tableView  cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSString *text = @"my long text";

    static NSString *MyIdentifier = @"MyIdentifier";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero  reuseIdentifier:identifier] autorelease];
    }

    CGFloat width = [UIScreen mainScreen].bounds.size.width - 50;
    CGFloat height = [self textHeight:text] + 10;
    CGRect frame = CGRectMake(10.0f, 10.0f, width, height);

    UILabel *cellLabel = [[UILabel alloc] initWithFrame:frame];
    cellLabel.tag = CELL_LABEL_TAG;
    cellLabel.textColor = [UIColor blackColor];
    cellLabel.backgroundColor = [UIColor clearColor];
    cellLabel.textAlignment = UITextAlignmentLeft;
    cellLabel.font = [UIFont systemFontOfSize:12.0f];
    [cell.contentView addSubview:cellLabel];
    [cellLabel release];

    return cell;
}

UILabel *label = (UILabel *)[cell viewWithTag:CELL_LABEL_TAG];
label.text = text;
label.numberOfLines = 0;
[label sizeToFit];
return cell;

Также используйте метод NSStringsizeWithFont:constrainedToSize:lineBreakMode: для вычисления высоты текста.

Ответ принят как подходящий

sizeWithFont constrainedToSize:lineBreakMode: - это метод, который нужно использовать. Пример того, как его использовать, приведен ниже:

//Calculate the expected size based on the font and linebreak mode of your label
// FLT_MAX here simply means no constraint in height
CGSize maximumLabelSize = CGSizeMake(296, FLT_MAX);

CGSize expectedLabelSize = [yourString sizeWithFont:yourLabel.font constrainedToSize:maximumLabelSize lineBreakMode:yourLabel.lineBreakMode];   

//adjust the label the the new height.
CGRect newFrame = yourLabel.frame;
newFrame.size.height = expectedLabelSize.height;
yourLabel.frame = newFrame;

Здесь используется 9999, как бы вы сделали его гибким для текста?

quantumpotato 06.04.2012 20:44

@quantumpotato 9999 - это просто заполнитель для максимального пространства, которое может занимать текст. Вы можете использовать там любой номер, который подходит для вашего пользовательского интерфейса.

PyjamaSam 10.04.2012 23:24

Есть ли способ использовать разрыв строки с помощью этого метода?

Sami 14.08.2012 21:26

Если вы подбираете размеры своих этикеток таким образом, вы делать неправильно. Вам следует использовать [label sizeToFit].

Marián Černý 26.04.2013 10:26

Не забывайте, что sizeWithFont устарел в iOS 7. stackoverflow.com/questions/18897896/…

attomos 11.01.2014 14:48

как это сделать быстро, пожалуйста, кто-нибудь может мне с этим помочь?

Kamal Upasena 13.05.2016 14:06

Вместо этого используйте boundingRectWithSize

Viktor Malyi 30.08.2016 16:43

устарело. Обновите ответ, пожалуйста

Vyachaslav Gerchicov 12.04.2017 16:00

Неужто просто использовать sizeThatFits вместо sizeWithFont? Просто сначала убедитесь, что вы установили шрифт UILabel.

Leon 05.01.2018 18:50

Как сделать то же самое на свифте?

Amg91 27.11.2018 05:51

@ MariánČerný и @Leon sizeToFit и sizeThatFits не соответствуют потребностям человека, публикующего сообщения, если я не ошибаюсь. Оба эти метода регулируют как ширину, так и высоту - человеку нужен фиксированный и фиксированный размер шрифта и режим разрыва строки, а затем найти высоту, которая им подходит.

Le Mot Juiced 21.02.2020 16:23

Наконец, это сработало. Спасибо вам, ребята.

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

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

и (да, глупый я), я изменял размер метки по умолчанию в методе cellForRowAtIndexPath - я упускал из виду код, который я написал ранее:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

Спасибо за этот пост. Это мне очень помогло. В моем случае я также редактирую текст в отдельном контроллере представления. Я заметил, что когда использую:

[cell.contentView addSubview:cellLabel];

в tableView: cellForRowAtIndexPath: метод, чтобы представление метки постоянно отображалось поверх предыдущего представления каждый раз, когда я редактировал ячейку. Текст стал неровным, и когда что-то было удалено или изменено, предыдущая версия была видна под новой версией. Вот как я решил проблему:

if ([[cell.contentView subviews] count] > 0) {
    UIView *test = [[cell.contentView subviews] objectAtIndex:0];
    [test removeFromSuperview];
}
[cell.contentView insertSubview:cellLabel atIndex:0];

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

Одна строчка - ответ Криса неверен.

newFrame.size.height = maximumLabelSize.height;

должно быть

newFrame.size.height = expectedLabelSize.height;

В остальном это правильное решение.

Вы двигались в правильном направлении. Все, что вам нужно сделать, это:

myUILabel.numberOfLines = 0;
myUILabel.text = @"Enter large amount of text here";
[myUILabel sizeToFit];

Подходящий размер был именно тем, что мне было нужно для переноса текста, с моим UILabel.lineBreakMode = UILineBreakMode WordWrap; мой UILabel.numberOfLines = 0;

Jack BeNimble 05.03.2011 23:22

Гораздо более простое решение, чем ответ, помеченный как правильный, и он также работает.

memmons 27.03.2011 00:17

@Inder Kumar Rathore - я использую это для нескольких строк все время, поэтому numberOfLines = 0; Я предполагаю, что сначала отсутствует установка предпочтительной ширины, но я предполагал, что это уже было сделано с помощью инициализации UILabel.

DonnaLea 06.07.2011 05:42

@Donna .. Я не понимаю, с чем ты предпочитаешь ... ты говоришь о его раме ??

Inder Kumar Rathore 06.07.2011 14:52

@DonnaLea, Большое спасибо. Ваш простой подход к решению помог мне решить и мою проблему.

Naved 18.11.2011 09:47

Перед вызовом sizeToFit мне пришлось сбросить ширину. [[текстовая метка ячейки] setFrame: CGRectMake (10, 10, 210, kCellMinHeight)]; [[текстовая метка ячейки] sizeToFit];

David Douglas 11.06.2013 15:38

У меня это не работает. У меня возникла проблема, когда sizeToFit регулировал ширину, а также высоту, и моя этикетка сжималась.

LightningStryk 07.08.2013 22:01

Что делать, если мне нужно знать размер?

Developer 24.02.2016 11:35

@Developer вы можете запросить фрейм после вызова sizeToFit. Но если вам нужно знать размер, это тоже может быть неправильным подходом для вас.

DonnaLea 25.02.2016 20:55

Спасибо, ребята, за помощь, вот код, который я пробовал, и он у меня работает.

   UILabel *instructions = [[UILabel alloc]initWithFrame:CGRectMake(10, 225, 300, 180)];
   NSString *text = @"First take clear picture and then try to zoom in to fit the ";
   instructions.text = text;
   instructions.textAlignment = UITextAlignmentCenter;
   instructions.lineBreakMode = NSLineBreakByWordWrapping;
   [instructions setTextColor:[UIColor grayColor]];

   CGSize expectedLabelSize = [text sizeWithFont:instructions.font 
                                constrainedToSize:instructions.frame.size
                                    lineBreakMode:UILineBreakModeWordWrap];

    CGRect newFrame = instructions.frame;
    newFrame.size.height = expectedLabelSize.height;
    instructions.frame = newFrame;
    instructions.numberOfLines = 0;
    [instructions sizeToFit];
    [self addSubview:instructions];

sizeWithFont устарел.

msmq 30.07.2015 12:03
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    cellIdentifier = @"myCell";
    cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    cell.myUILabel.lineBreakMode = UILineBreakModeWordWrap;        
    cell.myUILabel.numberOfLines = 0;
    cell.myUILabel.text = @"Some very very very very long text....."
    [cell.myUILabel.criterionDescriptionLabel sizeToFit];    
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
    CGFloat rowHeight = cell.myUILabel.frame.size.height + 10;

    return rowHeight;    
}

Не могли бы вы пояснить, как ваше решение решает проблему OP?

user577537 03.10.2012 18:59

вы не можете спросить UITableViewCell * cell = [self tableView: tableView cellForRowAtIndexPath: indexPath]; в heightForRowAtIndexPath вы получите бесконечный цикл

Peter Lapisu 03.05.2013 19:50

Вот версия категории:

UILabel + AutoSize.h #Импортировать

@interface UILabel (AutoSize)

- (void) autosizeForWidth: (int) width;

@end

UILabel + AutoSize.m

#import "UILabel+AutoSize.h"

@implementation UILabel (AutoSize)

- (void) autosizeForWidth: (int) width {
    self.lineBreakMode = UILineBreakModeWordWrap;
    self.numberOfLines = 0;
    CGSize maximumLabelSize = CGSizeMake(width, FLT_MAX);
    CGSize expectedLabelSize = [self.text sizeWithFont:self.font constrainedToSize:maximumLabelSize lineBreakMode:self.lineBreakMode];
    CGRect newFrame = self.frame;
    newFrame.size.height = expectedLabelSize.height;
    self.frame = newFrame;
}

@end
UILabel *itemTitle = [[UILabel alloc] initWithFrame:CGRectMake(10.0f, 10,100, 200.0f)];
itemTitle.text = @"aseruy56uiytitfesh";
itemTitle.adjustsFontSizeToFitWidth = NO;
itemTitle.autoresizingMask = UIViewAutoresizingFlexibleWidth;
itemTitle.font = [UIFont boldSystemFontOfSize:18.0];
itemTitle.textColor = [UIColor blackColor];
itemTitle.shadowColor = [UIColor whiteColor];
itemTitle.shadowOffset = CGSizeMake(0, 1);
itemTitle.backgroundColor = [UIColor blueColor];
itemTitle.lineBreakMode = UILineBreakModeWordWrap;
itemTitle.numberOfLines = 0;
[itemTitle sizeToFit];
[self.view addSubview:itemTitle];

используйте здесь все свойства, используемые на этикетке, и проверьте его, увеличив текст в itemTitle.text как

itemTitle.text = @"diofgorigjveghnhkvjteinughntivugenvitugnvkejrfgnvkhv";

он покажет правильный ответ, как вам нужно

При включенном autoLayout изменение размера не работает :)

В iOS 6 Apple добавила свойство UILabel, которое значительно упрощает динамическое изменение размера меток по вертикали: предпочтительныйMaxLayoutWidth.

Использование этого свойства в сочетании с методами lineBreakMode = NSLineBreakByWordWrapping и sizeToFit позволяет легко изменить размер экземпляра UILabel до высоты, которая вмещает весь текст.

Цитата из документации iOS:

preferredMaxLayoutWidth The preferred maximum width (in points) for a multiline label.

Discussion This property affects the size of the label when layout constraints are applied to it. During layout, if the text extends beyond the width specified by this property, the additional text is flowed to one or more new lines, thereby increasing the height of the label.

Образец:

...
UILabel *status = [[UILabel alloc] init];
status.lineBreakMode = NSLineBreakByWordWrapping;
status.numberOfLines = 5; // limits to 5 lines; use 0 for unlimited.

[self addSubview:status]; // self here is the parent view

status.preferredMaxLayoutWidth = self.frame.size.width; // assumes the parent view has its frame already set.

status.text = @"Some quite lengthy message may go here…";
[status sizeToFit];
[status setNeedsDisplay];
...

Обновления согласно iOS7

// If description are available for protocol
protocolDescriptionLabel.text = [dataDictionary objectForKey:@"description"];
[protocolDescriptionLabel sizeToFit];
[protocolDescriptionLabel setLineBreakMode:NSLineBreakByWordWrapping];

CGSize expectedLabelSize = [protocolDescriptionLabel
               textRectForBounds:protocolDescriptionLabel.frame
               limitedToNumberOfLines:protocolDescriptionLabel.numberOfLines].size;
NSLog(@"expectedLabelSize %f", expectedLabelSize.height);

//adjust the label the the new height.
CGRect newFrame = protocolDescriptionLabel.frame;
newFrame.size.height = expectedLabelSize.height;
protocolDescriptionLabel.frame = newFrame;

Этот метод будет работать как для iOS 6, так и для 7.

- (float)heightForLabelSize:(CGSize)maximumLabelSize  Font:(UIFont *)font String:(NSString*)string {

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
    NSDictionary *stringAttributes = [NSDictionary dictionaryWithObject:font forKey: NSFontAttributeName];

    CGSize adjustedLabelSize = [string maximumLabelSize
                                                                  options:NSStringDrawingTruncatesLastVisibleLine|NSStringDrawingUsesLineFragmentOrigin
                                                               attributes:stringAttributes context:nil].size;
    return adjustedLabelSize.height;
}
else {
    CGSize adjustedLabelSize = [string sizeWithFont:font constrainedToSize:maximumLabelSize lineBreakMode:NSLineBreakByWordWrapping];

    return adjustedLabelSize.height;
}

}

Вы также можете использовать это как метод. @Pyjamasam - это правда, поэтому я просто делаю свой метод. Это может быть полезно для кого-то другого

-(CGRect)setDynamicHeightForLabel:(UILabel*)_lbl andMaxWidth:(float)_width{
    CGSize maximumLabelSize = CGSizeMake(_width, FLT_MAX);

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

    //adjust the label the the new height.
    CGRect newFrame = _lbl.frame;
    newFrame.size.height = expectedLabelSize.height;
    return newFrame;
}

и просто установите это так

label.frame = [self setDynamicHeightForLabel:label andMaxWidth:300.0];

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

Единственное реальное решение здесь: https://stackoverflow.com/a/4214978/699944, а суть в том, чтобы использовать CoreText для ручного вычисления высоты каждой строки, чтобы получить правильный размер. Другого известного способа сделать это не существует.

Решение для iOS7 ранее и iOS7 выше

//
//  UILabel+DynamicHeight.m
//  For StackOverFlow
//
//  Created by Vijay on 24/02/14.
//  Copyright (c) 2014 http://Vijay-Apple-Dev.blogspot.com. All rights reserved.
//

#import <UIKit/UIKit.h>

#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)

#define SYSTEM_VERSION_LESS_THAN(v)                 ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)

#define iOS7_0 @"7.0"

@interface UILabel (DynamicHeight)

/*====================================================================*/

/* Calculate the size,bounds,frame of the Multi line Label */

/*====================================================================*/
/**
 *  Returns the size of the Label
 *
 *  @param aLabel To be used to calculte the height
 *
 *  @return size of the Label
 */

-(CGSize)sizeOfMultiLineLabel;

@end


//
//  UILabel+DynamicHeight.m
//  For StackOverFlow
//
//  Created by Vijay on 24/02/14.
//  Copyright (c) 2014 http://Vijay-Apple-Dev.blogspot.com. All rights reserved.
//

#import "UILabel+DynamicHeight.h"

@implementation UILabel (DynamicHeight)
/*====================================================================*/

/* Calculate the size,bounds,frame of the Multi line Label */

/*====================================================================*/
/**
 *  Returns the size of the Label
 *
 *  @param aLabel To be used to calculte the height
 *
 *  @return size of the Label
 */
-(CGSize)sizeOfMultiLineLabel{

    NSAssert(self, @"UILabel was nil");

    //Label text
    NSString *aLabelTextString = [self text];

    //Label font
    UIFont *aLabelFont = [self font];

    //Width of the Label
    CGFloat aLabelSizeWidth = self.frame.size.width;


    if (SYSTEM_VERSION_LESS_THAN(iOS7_0)) {
        //version < 7.0

        return [aLabelTextString sizeWithFont:aLabelFont
                            constrainedToSize:CGSizeMake(aLabelSizeWidth, MAXFLOAT)
                                lineBreakMode:NSLineBreakByWordWrapping];
    }
    else if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(iOS7_0)) {
        //version >= 7.0

        //Return the calculated size of the Label
        return [aLabelTextString boundingRectWithSize:CGSizeMake(aLabelSizeWidth, MAXFLOAT)
                                              options:NSStringDrawingUsesLineFragmentOrigin
                                           attributes:@{
                                                        NSFontAttributeName : aLabelFont
                                                        }
                                              context:nil].size;

    }

    return [self bounds].size;

}

@end

Где я должен вызывать этот метод в подклассе UITableViewController?

Homam 03.05.2014 09:44

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

Vijay-Apple-Dev.blogspot.com 05.05.2014 09:45

Виджай sizeWithFont лишен свободы.

user3182143 09.01.2018 10:07

А для тех, кто переходит на iOS 8, вот расширение класса для Swift:

extension UILabel {

    func autoresize() {
        if let textNSString: NSString = self.text {
            let rect = textNSString.boundingRectWithSize(CGSizeMake(self.frame.size.width, CGFloat.max),
                options: NSStringDrawingOptions.UsesLineFragmentOrigin,
                attributes: [NSFontAttributeName: self.font],
                context: nil)
            self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, rect.height)
        }
    }

}

Поскольку sizeWithFont устарел, я использую его.

этот получает специфические атрибуты ярлыка.

-(CGFloat)heightForLabel:(UILabel *)label withText:(NSString *)text{

    NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:text attributes:@{NSFontAttributeName:label.font}];
    CGRect rect = [attributedText boundingRectWithSize:(CGSize){label.frame.size.width, CGFLOAT_MAX}
                                           options:NSStringDrawingUsesLineFragmentOrigin
                                           context:nil];

    return ceil(rect.size.height);
}
NSString *str = @"Please enter your text......";
CGSize lblSize = [str sizeWithFont:[UIFont systemFontOfSize:15] constrainedToSize: CGSizeMake(200.0f, 600.0f) lineBreakMode: NSLineBreakByWordWrapping];

UILabel *label = [[UILabel alloc]init];
label.frame = CGRectMake(60, 20, 200, lblSize.height);
label.numberOfLines = 0;
label.lineBreakMode = NSLineBreakByWordWrapping;
label.font = [UIFont systemFontOfSize:15];
label.text = str;
label.backgroundColor = [UIColor clearColor];
[label sizeToFit];
[self.view addSubview:label];

Мой код:

UILabel *label      = [[UILabel alloc] init];
label.numberOfLines = 0;
label.lineBreakMode = NSLineBreakByWordWrapping;
label.text          = text;
label.textAlignment = NSTextAlignmentCenter;
label.font          = [UIFont fontWithName:_bodyTextFontFamily size:_bodyFontSize];

CGSize size = [label sizeThatFits:CGSizeMake(width, MAXFLOAT)];


float height        = size.height;
label.frame         = CGRectMake(x, y, width, height);

Вместо того, чтобы делать это программно, вы можете сделать это в раскадровке / XIB во время проектирования.

  • Установите для свойства количество строк UIlabel значение 0 в инспекторе атрибутов.
  • Затем установите ограничение ширины / (или) ведущее и конечное ограничение в соответствии с требованиями.
  • Затем установить ограничение высоты с минимальное значение. Наконец, выберите добавленное ограничение высоты и в инспекторе размеров то, которое находится рядом с инспектором атрибутов, менять - ограничение высоты связь из равно - больше чем.

Этот работает для UILabel, встроенного в настраиваемую ячейку xib в UITableView.

Gang Fang 19.04.2019 02:01

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

Hamid Reza Ansari 01.04.2020 18:57

Обновленный метод

+ (CGFloat)heightForText:(NSString*)text font:(UIFont*)font withinWidth:(CGFloat)width {

    CGSize constraint = CGSizeMake(width, 20000.0f);
    CGSize size;

    CGSize boundingBox = [text boundingRectWithSize:constraint
                                                  options:NSStringDrawingUsesLineFragmentOrigin
                                               attributes:@{NSFontAttributeName:font}
                                                  context:nil].size;

    size = CGSizeMake(ceil(boundingBox.width), ceil(boundingBox.height));

    return size.height;
}

Swift 2:

    yourLabel.text = "your very long text"
    yourLabel.numberOfLines = 0
    yourLabel.lineBreakMode = NSLineBreakMode.ByWordWrapping
    yourLabel.frame.size.width = 200
    yourLabel.frame.size.height = CGFloat(MAXFLOAT)
    yourLabel.sizeToFit()

Интересные строки - это sizeToFit() в сочетании с установкой frame.size.height на максимальное значение с плавающей запятой, это даст место для длинного текста, но sizeToFit() заставит его использовать только необходимое, но ВСЕГДА вызывает его после установки .frame.size.height.

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

yourLabel.frame.height - свойство только для получения
Phil Hudson 11.03.2016 07:38

yourLabel.frame.size.width и yourLabel.frame.size.height также доступны только для чтения

CalZone 13.01.2017 02:46

Этот метод даст идеальную высоту

-(float) getHeightForText:(NSString*) text withFont:(UIFont*) font andWidth:(float) width{
CGSize constraint = CGSizeMake(width , 20000.0f);
CGSize title_size;
float totalHeight;


title_size = [text boundingRectWithSize:constraint
                                options:NSStringDrawingUsesLineFragmentOrigin
                             attributes:@{ NSFontAttributeName : font }
                                context:nil].size;

totalHeight = ceil(title_size.height);

CGFloat height = MAX(totalHeight, 40.0f);
return height;
}

Не копируйте контент из других источников без четкой ссылки на источник. Это рассматривается как плагиат. См. stackoverflow.com/help/referencing (stackoverflow.com/a/25158206/444991).

Matt 08.04.2016 20:20

Проверьте эту работу отлично, не добавляя ни одной строчки кода. (Использование автолайма)

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

Автоматическое изменение размера UIView и UILabel

Пошаговое руководство: -

Шаг 1 :- Установить ограничение на UIView

1) В начале 2) В начале 3) В конце (из основного просмотра)

Шаг 2 :- Установить ограничение на метку 1

1) Ведущий 2) Верхний 3) Отслеживающий (из его супервизора)

Шаг 3 :- Установить ограничение на метку 2

1) В начале 2) В конце (из его супервизора)

Шаг 4: -Самый хитрый дает боттон UILabel из UIView.

Шаг 5: - (Необязательно) Установить ограничение на UIButton

1) В начале 2) Внизу 3) В конце 4) Фиксированная высота (из основного вида)

Выход :-

Примечание :- Убедитесь, что вы установили Number of lines = 0 в свойстве Label.

Я надеюсь, что этой информации достаточно для понимания Autoresize UIView в соответствии с высотой UILabel и Autoresize UILabel в соответствии с текстом.

А что, если вы захотите также иметь некоторые виды на белом фоне? Если вы не укажете высоту, в SB появятся несколько красных линий для «Требуются ограничения для: положения Y или высоты».

Bogdan Razvan 11.06.2018 16:41

это необходимо отметить как правильный ответ. Это правильный путь с ib.

Rana Tallal 13.03.2019 00:07

@ SPQR3 в чем проблема? это помогло многим людям, и его работа отлично.

Badal Shah 07.01.2020 06:23

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

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

myLabel.text = "your very long text"
myLabel.numberOfLines = 0
myLabel.lineBreakMode = NSLineBreakMode.ByWordWrapping

Установите ограничения для UILabel в раскадровке, включая верхний левый нижний правый

Для этого в Swift3 следующий код:

 let labelSizeWithFixedWith = CGSize(width: 300, height: CGFloat.greatestFiniteMagnitude)
            let exactLabelsize = self.label.sizeThatFits(labelSizeWithFixedWith)
            self.label.frame = CGRect(origin: CGPoint(x: 20, y: 20), size: exactLabelsize)

Это одна строка кода для получения высоты UILabel с помощью Objective-c:

labelObj.numberOfLines = 0;
CGSize neededSize = [labelObj sizeThatFits:CGSizeMake(screenWidth, CGFLOAT_MAX)];

и используя .height, вы получите высоту метки следующим образом:

neededSize.height

Лучший текущий ответ.

Mike 29.01.2020 01:19

Мой подход к вычислению динамической высоты UILabel.

    let width = ... //< width of this label 
    let text = ... //< display content

    label.numberOfLines = 0
    label.lineBreakMode = .byWordWrapping
    label.preferredMaxLayoutWidth = width

    // Font of this label.
    //label.font = UIFont.systemFont(ofSize: 17.0)
    // Compute intrinsicContentSize based on font, and preferredMaxLayoutWidth
    label.invalidateIntrinsicContentSize() 
    // Destination height
    let height = label.intrinsicContentSize.height

Перенести в функцию:

func computeHeight(text: String, width: CGFloat) -> CGFloat {
    // A dummy label in order to compute dynamic height.
    let label = UILabel()

    label.numberOfLines = 0
    label.lineBreakMode = .byWordWrapping
    label.font = UIFont.systemFont(ofSize: 17.0)

    label.preferredMaxLayoutWidth = width
    label.text = text
    label.invalidateIntrinsicContentSize()

    let height = label.intrinsicContentSize.height
    return height
}

Добавляя к приведенным выше ответам:

Этого легко добиться с помощью раскадровки.

  1. Установите ограничение для UILabel. (В моем случае я использовал верхнюю, левую и фиксированную ширину)
  2. Установите Количество строк до 0 в инспекторе атрибутов
  3. Установите Разрыв строки до WordWrap в инспекторе атрибутов.

UILabel Height Adjust

Расширение UILabel на основе этот ответ для Swift 4 и выше

extension UILabel {

    func retrieveTextHeight () -> CGFloat {
        let attributedText = NSAttributedString(string: self.text!, attributes: [NSFontAttributeName:self.font])

        let rect = attributedText.boundingRect(with: CGSize(width: self.frame.size.width, height: CGFloat.greatestFiniteMagnitude), options: .usesLineFragmentOrigin, context: nil)

        return ceil(rect.size.height)
    }

}

Может использоваться как:

self.labelHeightConstraint.constant = self.label.retrieveTextHeight()

Вы можете получить высоту, используя приведенный ниже код

Вы должны пройти

  1. текст 2. шрифт 3. ширина метки

    func heightForLabel(text: String, font: UIFont, width: CGFloat) -> CGFloat {
    
       let label:UILabel = UILabel(frame: CGRect(x: 0, y: 0, width: width, height: CGFloat.greatestFiniteMagnitude))
       label.numberOfLines = 0
       label.lineBreakMode = NSLineBreakMode.byWordWrapping
       label.font = font
       label.text = text
       label.sizeToFit()
    
       return label.frame.height
    }
    

Другие вопросы по теме