根据文本调整 UILabel 高度
Posted
技术标签:
【中文标题】根据文本调整 UILabel 高度【英文标题】:Adjust UILabel height depending on the text 【发布时间】:2010-10-01 13:51:13 【问题描述】:考虑我在UILabel
(一长行动态文本)中有以下文本:
由于外星人军队的数量远远超过团队,玩家必须利用世界末日后的世界来发挥自己的优势,例如在垃圾箱、柱子、汽车、瓦砾和其他物体后面寻找掩护。
我想调整 UILabel's
的高度以适应文本。我正在使用 UILabel
的以下属性来使其中的文本换行。
myUILabel.lineBreakMode = UILineBreakModeWordWrap;
myUILabel.numberOfLines = 0;
如果我没有朝着正确的方向前进,请告诉我。谢谢。
【问题讨论】:
另见:***.com/questions/406212/… Swift 版本低于:***.com/a/33945342/1634890 【参考方案1】: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 9999 只是文本允许占用的最大空间的占位符。您可以使用任何适用于您的 UI 的数字。 这种方法到底有没有用换行符? 如果您像这样调整标签大小,您就是doing it wrong。你应该使用[label sizeToFit]
。
不要忘记 sizeWithFont
在 ios 7 中已被弃用。***.com/questions/18897896/…【参考方案2】:
你的方向是正确的。您需要做的就是:
myUILabel.numberOfLines = 0;
myUILabel.text = @"Enter large amount of text here";
[myUILabel sizeToFit];
【讨论】:
适合的大小正是我需要让文本换行的大小,很长,myUILabel.lineBreakMode = UILineBreakModeWordWrap; myUILabel.numberOfLines = 0; 一个比标记为正确的答案更简单的解决方案,而且效果也很好。 @Inder Kumar Rathore - 我一直将它用于多行,因此 numberOfLines = 0;我猜它缺少首先设置首选宽度,但我假设已经使用 UILabel 的 init 完成了。 @Donna..我不喜欢你的首选..你是在谈论它的框架吗?? @DonnaLea,非常感谢。您对解决方案的简单方法也帮助我解决了我的问题。【参考方案3】:在 iOS 6 中,Apple 为 UILabel 添加了一个属性,该属性极大地简化了标签的动态垂直调整大小:preferredMaxLayoutWidth。
将此属性与 lineBreakMode = NSLineBreakByWordWrapping 和 sizeToFit 方法结合使用,可以轻松地将 UILabel 实例的大小调整为可容纳整个文本的高度。
引用 iOS 文档:
preferredMaxLayoutWidth 多行标签的首选最大宽度(以磅为单位)。 讨论 当应用布局约束时,此属性会影响标签的大小。在布局期间,如果文本超出此属性指定的宽度,则附加文本将流动到一个或多个新行,从而增加标签的高度。
一个样本:
...
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];
...
【讨论】:
【参考方案4】:在不添加单行代码的情况下完美检查这项工作。 (使用自动布局)
我根据你的要求为你做了一个demo。从下面的链接下载它,
Autoresize UIView and UILabel
分步指南:-
第 1 步:- 将约束设置为 UIView
1) 领先 2) 前 3) 尾随(从主视图)
第 2 步:- 将约束设置为标签 1
1) 领先 2) 前 3) 尾随(来自它的超级视图)
第 3 步:- 将约束设置为标签 2
1) 领先 2) 尾随(来自它的超级视图)
第 4 步:- 最棘手的从 UIView 将 botton 给 UILabel。
第 5 步:-(可选)将约束设置为 UIButton
1) 领先 2) 底部 3) 尾随 4) 固定高度(从主视图)
输出:-
注意:-请确保您已在 Label 属性中设置 Number of lines =0。
我希望这些信息足以理解 Autoresize UIView 根据 UILabel 的高度和 Autoresize UILabel 根据文本。
【讨论】:
如果你想在白色背景视图下也有一些视图怎么办?不给它一个高度会在 SB 中显示一些红线“需要约束:Y 位置或高度” 这需要标记为正确答案。这是使用 ib 的正确方法。 @SPQR3 有什么问题?它帮助了很多人并且工作正常。【参考方案5】:您可以在设计时在 Storyboard/XIB 中执行此操作,而不是以编程方式执行此操作。
在属性检查器中将 UIlabel 的 行数 属性设置为 0。 然后根据要求设置宽度约束/(或)前导和尾随约束。 然后设置高度限制与最小值。最后选择您添加的高度约束,并在尺寸检查器中属性检查器旁边的一个,更改高度约束的关系从等于 - 大于。【讨论】:
这个适用于嵌入在 UITableView 中的自定义 xib 单元格中的 UILabel。 根据您的回答,我为我的标签设置了一个恒定的高度,并将该优先级设置为 Low (250) 并且错误消失了。 (不需要设置等于-大于)【参考方案6】:感谢大家的帮助,这是我尝试过的代码
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 已弃用。【参考方案7】:iOS7 之前和iOS7 以上的解决方案
//
// UILabel+DynamicHeight.m
// For ***
//
// 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 ***
//
// 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的子类中,应该在哪里调用这个方法? 你想在哪里计算标签高度然后调用这个方法。然后调整表格视图的高度。您在索引方法处有行的表格视图高度。根据需要计算所有垂直标签文本 Vijay sizeWithFont 已被贬低。【参考方案8】:因为 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);
【讨论】:
【参考方案9】:基于this answer 的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()
【讨论】:
【参考方案10】:这是一个分类版本:
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
【讨论】:
【参考方案11】:您可以通过以下方式实现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:
方法来计算文本的高度。
【讨论】:
【参考方案12】:我计算 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
【讨论】:
【参考方案13】:对于那些正在迁移到 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)
【讨论】:
【参考方案14】:对我来说最简单和更好的方法是将高度限制应用于标签并将优先级设置为低,即情节提要中的 (250)。
因此,借助故事板,您无需担心以编程方式计算高度和宽度。
【讨论】:
【参考方案15】:更新方法
+ (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;
【讨论】:
【参考方案16】:这是使用 Objective-c 获取 UILabel 高度的一行代码:
labelObj.numberOfLines = 0;
CGSize neededSize = [labelObj sizeThatFits:CGSizeMake(screenWidth, CGFLOAT_MAX)];
使用 .height 你会得到如下标签的高度:
neededSize.height
【讨论】:
当前最佳答案。【参考方案17】:您可以使用以下代码获取高度
你必须通过
文字 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
【讨论】:
【参考方案18】:感谢这篇文章。这对我帮助很大。就我而言,我还在单独的视图控制器中编辑文本。我注意到当我使用时:
[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];
不再有奇怪的分层。如果有更好的处理方法,请告诉我。
【讨论】:
【参考方案19】: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";
它将根据您的需要显示完美的答案
【讨论】:
【参考方案20】:您也可以将其用作方法。 @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];
【讨论】:
【参考方案21】:在 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)
【讨论】:
【参考方案22】:补充以上答案:
这可以通过故事板轻松实现。
-
为 UILabel 设置约束。(在我的例子中,我做了顶部、左侧和固定宽度)
在属性检查器中设置行数为0
在属性检查器中将换行符设置为 WordWrap。
【讨论】:
【参考方案23】:一行是克里斯的答案是错误的。
newFrame.size.height = maximumLabelSize.height;
应该是
newFrame.size.height = expectedLabelSize.height;
除此之外,这是正确的解决方案。
【讨论】:
【参考方案24】:终于成功了。谢谢各位。
我没有让它工作,因为我试图在heightForRowAtIndexPath
方法中调整标签的大小:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
并且(是的,我很傻),我在 cellForRowAtIndexPath
方法中将标签大小调整为默认值 - 我忽略了我之前编写的代码:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
【讨论】:
【参考方案25】:-(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 的问题? 你不能问 UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];在 heightForRowAtIndexPath 中,你会得到无限循环【参考方案26】: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];
【讨论】:
【参考方案27】:我的代码:
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);
【讨论】:
【参考方案28】:这种方法会给出完美的高度
-(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;
【讨论】:
请勿在没有明确归属的情况下从其他地方复制内容。它被视为剽窃。请参阅***.com/help/referencing (***.com/a/25158206/444991)。【参考方案29】:斯威夫特 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
是一个只能获取的属性
yourLabel.frame.size.width 和 yourLabel.frame.size.height 也是只读的【参考方案30】:
myLabel.text = "your very long text"
myLabel.numberOfLines = 0
myLabel.lineBreakMode = NSLineBreakMode.ByWordWrapping
请在情节提要中为 UILable 设置约束,包括左上右下
【讨论】:
以上是关于根据文本调整 UILabel 高度的主要内容,如果未能解决你的问题,请参考以下文章