UILabel-自动调整标签大小以适合文本?


144

是否可以自动调整UILabel框/边界的大小以适合所包含的文本?(我不在乎它最终是否大于显示屏)

因此,如果用户输入“你好”或“我的名字真的很长,我希望它适合此框”,它不会被截断并且标签会相应地“加宽”吗?


任何人都请帮我提供SWIFT代码..
天使˚FSYRUS

Answers:


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 2014年

1
当文本少/多时,UILabel不会自动调整大小。我正在使用自动版式。尝试制作UILabel,但是每次cellForRowAtIndex初始化时都会创建它们。尝试了很多事情。对我没有任何帮助。uilabel的背景采用相同的宽度。救命 !!!
coreDeviOS 2014年

@Daniel我将行数设置为= 0,但是它不起作用。我设置了水平和垂直居中的约束。我做了一个额外的事情是由的UILabel的一个子类,并使用它的那个标签
Jasmeet

使用自动布局时,最简单的解决方案是:(1)将线设置为0,(2)将常数为0的宽度约束设置为“大于或等于”,(3)将常数为0的高度约束设置为“大于或等于”,( 4)像往常一样对齐,例如,水平和垂直居中。
Erik van der Neut

76

使用[label sizeToFit];将获得与Daniels Category相同的结果。

尽管我建议使用自动布局,并让标签根据约束来调整自身大小。


3
使用swift时,我必须使用dispatch_async(dispatch_get_main_queue(),{})在主线程上运行此代码;
Zeezer

@Zeezer你知道为什么吗?
FurloSK

13
@FurloSK ui上的任何更改都必须在主线程中完成。
Guilherme Torres Castro

32

如果我们希望UILabel根据文字大小缩小和扩展,则带自动布局的情节提要是最好的选择。以下是实现此目的的步骤

脚步

  1. 将UILabel放在视图控制器中,然后将其放置在所需的位置。也0用于的numberOfLines属性UILabel

  2. 给它加上顶部,前导和尾随的空间图钉约束。

在此处输入图片说明

  1. 现在,它将发出警告,单击黄色箭头。

在此处输入图片说明

  1. 单击,Update Frame然后单击Fix Misplacement。现在,如果文本较少,则该UILabel将缩小,如果文本较多,则将扩展。

1
我尚未针对本地化进行测试,但它也应该适用。
Yogesh Suthar

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"
        }
    }
  • 如果希望标签换行,则在IB中将行数设置为0并添加myLabel.preferredMaxLayoutWidth = 150 // or whatever代码。(我还将按钮固定在标签的底部,以便当标签高度增加时,按钮可以向下移动。)

在此处输入图片说明

  • 如果要在a中动态调整标签大小,UITableViewCell请参见此答案

在此处输入图片说明


嗨,我得到了调整大小的标签,但我不知道如何调整像元高度。您能否让我知道如何调整像元高度。
Vivek

@Vivek,只要您没有在高度上设置任何约束,它就会自动调整大小。
Suragch

是的,但是当我使用自定义单元格并在他的单元格中放置2个标签时,怎么可能。
Vivek

@Vivek,对不起,我看错了您的问题。通过回答这个问题,您是否已经获得一个标签可以使用?
Suragch


5

我根据上面Daniel的回复创建了一些方法。

-(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,此时该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. 如果您不想计算标签文本的大小,则可以在UILabel实例上使用-sizeToFit 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. 将UILabel的出口参考ID:label引用到Controller.h
  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文档中的何处。
阿迪尔·侯赛因
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.