根据文字调整UILabel的高度
考虑一下我在UILabel
(一长串dynamic文本)中有以下文本:
由于外星人军队远远超过了队伍,玩家必须利用后世界末日的世界,如在垃圾箱,柱子,汽车,瓦砾等物体后面寻找掩护。
我想调整UILabel's
高度,以便文本可以适应。我使用UILabel
以下属性来使文本内包装。
myUILabel.lineBreakMode = UILineBreakModeWordWrap; myUILabel.numberOfLines = 0;
请让我知道,如果我不是在正确的方向前进。 谢谢。
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添加了一个属性,这大大简化了标签的dynamic垂直resize: preferredMaxLayoutWidth 。
将此属性与lineBreakMode = NSLineBreakByWordWrapping和sizeToFit方法结合使用,可以轻松地将UILabel实例的大小调整为适应整个文本的高度。
来自iOS文档的引用:
preferredMaxLayoutWidth多行标签的首选最大宽度(以磅为单位)。
讨论当对其应用布局约束时,此属性会影响标签的大小。 在布局过程中,如果文本超出了此属性指定的宽度,则附加文本将stream向一个或多个新行,从而增加标签的高度。
一个样品:
... 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]; ...
而是以编程方式执行此操作,则可以在devise时在Storyboard / XIB中执行此操作。
- 在属性检查器中将UIlabel的行数属性设置为0 。
- 然后根据需要设置宽度约束/(或)前后约束。
- 然后用最小值 设置高度约束 。 最后select您添加的高度约束,并在尺寸检查器中select属性检查器旁边的高度约束,将高度约束关系从等于 – 大于 。
无需添加单行代码即可完美检查此工作。 (使用Autolayout)
我根据你的要求为你做了一个演示 。 从下面的链接下载,
自动调整UIView和UILabel
分步指南: –
第1步: –将约束设置为UIView
1)领导2)前3)尾随(从主视图)
第2步: –将约束设置为标签1
1)领先2)前3)追踪(从超级观点)
第3步: –将约束设置为标签2
1)领导2)追踪(从超级观点)
第4步: – 最棘手的从UIView给UILabel botton。
第5步: – (可选)将约束设置为UIButton
1)领导2)底部3)尾随4)固定高度(从主视图)
输出: –
注意: –确保你在Label属性中设置了行数= 0。
我希望这个信息足以了解根据UILabel的高度和Autoresize UILabel根据文本Autoresize UIView。
感谢大家的帮助,这里是我试过的代码,这是我的工作
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的解决scheme
// // 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 #import
@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
您可以通过以下方式实现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
的sizeWithFont:constrainedToSize:lineBreakMode:
方法来计算文本的高度。
为我工作的最简单和最好的方法是将高度约束应用于标签,并将优先级设置为低 ,即在故事板中(250)。
所以你不必担心计算高度和宽度,感谢故事板。
对于那些正在迁移到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) } } }
更新的方法
+ (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.text中的文本来testing它
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()
空间,但sizeToFit()
将强制它只使用必要的,但总是在设置.frame.size.height
。
我build议设置一个.backgroundColor
用于debugging目的,这样你可以看到为每个案例渲染的框架。
在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)
这是使用Objective-c获取UILabel高度的一行代码:
labelObj.numberOfLines = 0; CGSize neededSize = [labelObj sizeThatFits:CGSizeMake(screenWidth, CGFLOAT_MAX)];
并使用.height你将得到标签的高度如下:
neededSize.height
一句话是克里斯的答案是错的。
newFrame.size.height = maximumLabelSize.height;
应该
newFrame.size.height = expectedLabelSize.height;
除此之外,这是正确的解决scheme。
最后,它的工作。 感谢你们。
我没有得到它的工作,因为我试图调整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设置约束,包括左上angular的右下angular
我的方法来计算UILabel的dynamic高度。
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
包装function:
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 }
当启用autoLayout时,resize不起作用:)
问题是没有提到的function是可靠的,对于一些string和字体将返回不正确的高度值。 特别是会失败的归因文本。
唯一可行的解决scheme是这里: https ://stackoverflow.com/a/4214978/699944和重点是使用CoreText手动计算每一行的高度,以得到正确的大小。 没有其他已知的方法来做到这一点。
这种方法适用于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; } }