Отрегулируйте высоту UILabel в зависимости от текста
считайте, что у меня есть следующий текст в UILabel (длинная строка динамического текста):
Я хочу изменить размер UILabel's высота, чтобы текст мог вписаться. Я использую следующие свойства UILabel чтобы сделать текст внутри to упаковка.
myUILabel.lineBreakMode = UILineBreakModeWordWrap;
myUILabel.numberOfLines = 0;
пожалуйста, дайте мне знать, если я не двигаюсь в правильном направлении. Спасибо.
30 ответов:
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;
вы шли в правильном направлении. Все, что вам нужно сделать, это:
myUILabel.numberOfLines = 0; myUILabel.text = @"Enter large amount of text here"; [myUILabel sizeToFit];
в iOS 6 Apple добавила свойство UILabel что значительно упрощает динамическое вертикальное изменение размеров меток: preferredMaxLayoutWidth.
использование этого свойства в сочетании с lineBreakMode = NSLineBreakByWordWrapping и sizeToFit метод позволяет легко изменить размер экземпляра UILabel до высоты, которая вмещает весь текст.
цитата из iOS документация:
preferredMaxLayoutWidth Предпочтительная максимальная ширина (в точках) для многострочной надписи.
Обсуждение Это свойство влияет на размер метки при применении к ней ограничений компоновки. Во время компоновки, если текст выходит за пределы ширины, заданной этим свойством, дополнительный текст перетекает в одну или несколько новых строк, тем самым увеличивая высоту метки.A пример:
... 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]; ...
вместо того, чтобы делать это программно, вы можете сделать это в раскадровке или XIB при проектировании.
- установить UILabel ни это количество строк свойство 0 в инспекторе атрибутов.
- затем установите ограничение ширины / (или) ведущее и конечное ограничение в соответствии с требованием.
- затем установить ограничение по высоте С минимальное значение. Наконец, выберите ограничение по высоте, которое вы добавили, и в инспекторе размеров один рядом с инспектором атрибутов,изменить ограничение высоты отношения С равна -больше.
проверьте эту работу отлично, не добавляя ни одной строки кода. (С Помощью Автозапуска)
Я демо для вас согласно вашему требованию. Загрузите его по ссылке ниже,
автоматического изменения размеров наследник UIView и UILabel ни
Пошаговое Руководство: -
Шаг 1 :- установить ограничение на UIView
1) Ведущий 2) Топ 3) Трейлинг (От mainview)
Шаг 2 :- установить ограничение на метку 1
1) ведущий 2) Топ 3) трейлинг (из супервизора)
Шаг 3: установить ограничение на метку 2
1) ведущий 2) трейлинг (из супервизора)
Шаг 4 :-самое интересное дать боты для UILabel из UIView .
Шаг 5 :- (необязательно) установить ограничение на UIButton
1) ведущий 2) Нижний 3) задний 4) фиксированная высота (от mainview)
выход :-
Примечание: убедитесь, что вы установили количество строк =0 в ярлыка свойство.
Я надеюсь, что этой информации достаточно, чтобы понять Autoresize UIView в соответствии с высотой UILabel и Autoresize UILabel в соответствии с текстом.
Спасибо ребята за помощь, вот код, который я попробовал, который работает для меня
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];
решение для 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
Так как 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); }
вот версия категория:
UILabel+AutoSize.h #импорт
@interface UILabel (AutoSize) - (void) autosizeForWidth: (int) width; @endUILabel+AutoSize.м
#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
вы можете реализовать
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;использовать
NSString' ssizeWithFont:constrainedToSize:lineBreakMode:метод вычисления высоты текста.
а для тех, кто переходит на 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) } } }
самый простой и лучший способ, который работал для меня, - это применить ограничение высоты к метке и установить приоритет низкий, т. е. (250) в раскадровке.
Так что вам не нужно беспокоиться о вычислении высоты и ширины программно, благодаря раскадровке.
Обновленный Метод
+ (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; }
Спасибо за этот пост. Это мне очень помогло. В моем случае я также редактирую текст в отдельном контроллере вида. Я заметил, что когда я использую:
[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];нет больше странных слоев. Если есть лучший способ справиться с этим, пожалуйста, дайте мне знать.
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.текст как
itemTitle.text = @"diofgorigjveghnhkvjteinughntivugenvitugnvkejrfgnvkhv";он покажет perfetc ответ, как вам нужно
Вы можете использовать его в качестве метода, а также. @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];
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для целей отладки, таким образом, вы можете увидеть кадр, отображаемый для каждого случая.
для этого в 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)];и используя .высота вы получите высоту метки следующим образом:
neededSize.height
одна строка-это неправильный ответ Криса.
newFrame.size.height = maximumLabelSize.height;должно быть
newFrame.size.height = expectedLabelSize.height;кроме этого, это правильное решение.
наконец, это сработало. Спасибо, ребята.
Я не получаю его на работу, потому что я пытался изменить размер ярлыка в
heightForRowAtIndexPathспособ:- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPathи (да, глупый я), я изменял размер метки по умолчанию в
cellForRowAtIndexPathметод - я пропустил код, который я написал ранее:- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
-(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; }
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);
этот метод даст идеальную высоту
-(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; }
myLabel.text = "your very long text" myLabel.numberOfLines = 0 myLabel.lineBreakMode = NSLineBreakMode.ByWordWrappingпожалуйста, установите ограничения для UILable в раскадровке, включая верхний левый нижний правый
мой подход к вычислению динамической высоты 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 }
добавление к вышеприведенным ответам:
Это может быть легко достигнуто с помощью раскадровки.
- установить ограничение для UILabel.(В моем случае я сделал верхнюю, левую и фиксированную ширину)
- Set количество строк до 0 в Инспекторе атрибутов
- Set разрыв строки для перехода на новую строку в Инспекторе атрибутов.
расширение 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()
проблема в том, что ни одна из упомянутых функций не является реальной и для некоторых строк и шрифтов вернет неверное значение высоты. Особенно провалится для атрибутивных текстов.
единственное реальное решение здесь:https://stackoverflow.com/a/4214978/699944 и дело в том, чтобы использовать CoreText для ручного расчета высоты каждой строки, чтобы получить правильный размер. Нет другого известного способа сделать это.








Comments