UILabel不会自动缩小文本以适合标签大小

问题描述 投票:104回答:17

我有这个奇怪的问题,我现在处理它超过8小时..根据情况,我必须动态计算UILabels大小, 例如 我的UIViewController收到一个事件,我改变UILabels大小。从大到小。我的UILabel的大小变得更小,我得到正确的所需大小,但我的UILabel中的文本保持不变,相同的字体大小等。我需要字体变小,整个文本适合UILabel。所以问题是如何使文本适合我的标签与autoshrinking或类似的东西?

在我的xib中,UILabels autoshrink被检查,行数也设置为0,并且我的字符串也有新行符号(\ n),我选择了linebreakmode到wordwrap。也许有人和我现在处于同样的境地,可以帮助我吗?我真的很感激。

提前致谢!

编辑:UILabel最小字体大小设置为10

iphone objective-c ios cocoa-touch ipad
17个回答
150
投票

如果您仍在寻找更好的解决方案,我认为这就是您想要的:

一个布尔值,指示是否应缩小字体大小以使标题字符串适合标签的边界矩形。 (仅当numberOfLines属性设置为1时,此属性才有效。)

@property(nonatomic) BOOL adjustsFontSizeToFitWidth

一个布尔值,指示是否应调整字母之间的间距以适应标签边界矩形内的字符串。 (已弃用)

@property(nonatomic) BOOL adjustsLetterSpacingToFitWidth

Source


2
投票

两年过去了,这个问题仍然存在......

在iOS 8 / XCode 6.1中,我有时发现我的UILabel(在UITableViewCell中创建,AutoLayout打开,灵活约束,因此它有足够的空间)不会调整自身大小以适应文本字符串。

与前几年一样,解决方案是设置文本,然后调用sizeToFit

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    . . .
    cell.lblCreatedAt.text = [note getCreatedDateAsString];
    [cell.lblCreatedAt sizeToFit];
}

(叹。)


2
投票

在iOS 9中我只需要:

  1. 从标签的左侧和右侧添加约束到超级视图。
  2. 将换行模式设置为IB中的裁剪。
  3. 在IB中将行数设置为1。

有人建议将行数设置为0,但对我来说,这只是让标签转到多行......


1
投票

以下是如何操作。假设以下messageLabel是您想要具有所需效果的标签。现在,请尝试以下简单的代码行:

    //SET THE WIDTH CONSTRAINTS FOR LABEL.
    CGFloat constrainedWidth = 240.0f;//YOU CAN PUT YOUR DESIRED ONE,THE MAXIMUM WIDTH OF YOUR LABEL.
 //CALCULATE THE SPACE FOR THE TEXT SPECIFIED.
    CGSize sizeOfText=[yourText sizeWithFont:yourFont constrainedToSize:CGSizeMake(constrainedWidth, CGFLOAT_MAX) lineBreakMode:UILineBreakModeWordWrap];
    UILabel *messageLabel=[[UILabel alloc] initWithFrame:CGRectMake(20,20,constrainedWidth,sizeOfText.height)];
    messageLabel.text=yourText;
    messageLabel.numberOfLines=0;//JUST TO SUPPORT MULTILINING.

1
投票

如果numberOfLines > 1无效我做了什么使这样的条件 -

if(lblRecLocation.text.length > 100)
    lblRecLocation.font = [UIFont fontWithName:@"app_font_name" size:10];

1
投票

在Swift 4中(以编程方式):

let label = UILabel(frame: CGRect(x: 0, y: 0, width: 200.0, height: 200.0))
label.adjustsFontSizeToFitWidth = true
label.numberOfLines = 0

label.text = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum."

view.addSubview(label)

1
投票

这是一个很好的问题,因为感觉这将是内置的UIKit功能或相关框架的一部分。以下是该问题的一个很好的视觉示例:

周围没有简单的方法,但这绝对是可能的。一种方法是以编程方式尝试不同的字体大小,直到找到一个合适地接近视图边界的字体。你可以用boundingRect()NSStringNSAttributedString函数来完成这个。例如:

let string = "This is a test"
let infiniteSize = CGSize(width: CGFloat.greatestFiniteMagnitude, height:CGFloat.greatestFiniteMagnitude)
let size = string.boundingRect(with: infiniteSize, options: [], attributes: [.font: UIFont.systemFont(ofSize: avgSize)] context: nil).size

您可以进行二进制搜索,使其比完整的暴力方法更有效。如果你正在寻找一些非常强大的东西,还有一些考虑因素涉及更多,包括正确的自动换行和iOS字体缓存性能。

如果您只关心在屏幕上以简单的方式显示文本,我已经在Swift中开发了一个强大的实现,我也在生产应用程序中使用它。它是一个UIView子类,为任何输入文本(包括多行)提供高效的自动字体缩放。要使用它,您只需执行以下操作:

let view = AKTextView()
// Use a simple or fancy NSAttributedString
view.attributedText = .init(string: "Some text here")
// Add to the view hierarchy somewhere

而已!你可以在这里找到完整的来源:https://github.com/FlickType/AccessibilityKit

希望这可以帮助!


0
投票

迟到了,但由于我有额外的要求,每行一个字,这一个添加为我做了诀窍:

label.numberOfLines = [labelString componentsSeparatedByString:@" "].count;

Apple Docs说:

通常,标签文本使用您在font属性中指定的字体绘制。但是,如果此属性设置为YES,并且text属性中的文本超出了标签的边界矩形,则接收器将开始缩小字体大小,直到字符串适合或达到最小字体大小。在iOS 6及更早版本中,仅当numberOfLines属性设置为1时,此属性才有效。

但这是谎言。我告诉你的谎言!所有iOS版本都是如此。具体而言,当在UILabel中使用UICollectionViewCell时,这是正确的,其大小由在运行时通过自定义布局动态调整的约束确定(例如,self.menuCollectionViewLayout.itemSize = size)。

因此,当与之前的答案中提到的adjustsFontSizeToFitWidthminimumScaleFactor一起使用时,基于字数以编程方式设置numberOfLines解决了自动收缩问题。根据字数或甚至字符数进行类似的操作可能会产生“足够接近”的解决方案。


0
投票

Swift 4,Xcode 9.4.1

对我有用的解决方案:我在集合视图单元格中有一个标签,标签文本正在修剪。在Storyboard上设置如下属性

Lines = 0
LineBreak = Word Wrap
Set yourlabel's leading and trailing constraint = 0 (using Autolayout)

112
投票

这就是我在iOS 9.2,Xcode 7.2中让UILabel Autoshrink工作的原因(尤其是6s Plus故事板中4s设备中标签字体的高度)......

enter image description here

  • 行数为0
  • 换行符:剪辑
  • 自动收缩:最小字体比例0.25

67
投票

minimumFontSize在iOS 6中已弃用。

所以使用minimumScaleFactor而不是minmimumFontSize

lbl.adjustsFontSizeToFitWidth=YES;
lbl.minimumScaleFactor=0.5;

19
投票

我的解决方案是布尔标签.adjustsFontSizeToFitWidth = YES;但。您必须在界面生成器中将Word Wrapping切换为“CLIP”。然后自动收缩标签。这是非常重要的。


8
投票

在Swift 3(以编程方式)中,我必须这样做:

let lbl = UILabel()
lbl.numberOfLines = 0
lbl.lineBreakMode = .byClipping
lbl.adjustsFontSizeToFitWidth = true
lbl.minimumScaleFactor = 0.5
lbl.font = UIFont.systemFont(ofSize: 15)

5
投票

你可以这样写

UILabel *reviews = [[UILabel alloc]initWithFrame:CGRectMake(14, 13,270,30)];//Set frame
reviews.numberOfLines=0;
reviews.textAlignment = UITextAlignmentLeft;
reviews.font = [UIFont fontWithName:@"Arial Rounded MT Bold" size:12];
reviews.textColor=[UIColor colorWithRed:0.0/255.0 green:0.0/255.0 blue:0.0/255.0 alpha:0.8]; 
reviews.backgroundColor=[UIColor clearColor];

你可以计算这样的行数

CGSize maxlblSize = CGSizeMake(270,9999);
CGSize totalSize = [reviews.text sizeWithFont:reviews.font 
              constrainedToSize:maxlblSize lineBreakMode:reviews.lineBreakMode];

CGRect newFrame =reviews.frame;
newFrame.size.height = totalSize.height;
reviews.frame = newFrame;

CGFloat reviewlblheight = totalSize.height;

int lines=reviewlblheight/12;//12 is the font size of label

UILabel *lbl=[[UILabel alloc]init];
lbl.frame=CGRectMake(140,220 , 100, 25);//set frame as your requirement
lbl.font=[UIFont fontWithName:@"Arial" size:20];
[lbl setAutoresizingMask:UIViewContentModeScaleAspectFill];
[lbl setLineBreakMode:UILineBreakModeClip];
lbl.adjustsFontSizeToFitWidth=YES;//This is main for shrinking font
lbl.text=@"HelloHelloHello";

希望这会帮助你:-)等待你的回复


4
投票

这是适用于运行Xcode 8.2.1(8C1002)的Swift 3

我发现的最佳解决方案是在标签上的Storyboard或IB中设置固定宽度。通过约束边距来设置约束。在viewDidLoad中添加以下代码行:

override func viewDidLoad() {
            super.viewDidLoad()

            label.numberOfLines = 1
            label.adjustsFontSizeToFitWidth = true
            label.minimumScaleFactor = 0.5
        }

label constraints to margin

fixed width label constraints to margin

attributes inspector

这就像一个魅力,它不会溢出到一个新的行,并缩小文本以适应标签的宽度,没有任何奇怪的问题,并在Swift 3中工作。


3
投票

最后我没有找到答案。我认为自动收缩不适用于多行。我最终在这个链接中使用了建议:autoshrink on a UILabel with multiple lines

解决方案是计算给定宽度的文本高度,如果文本较大,则缩小字体大小然后再次相同,直到高度等于或小于所需大小。

我不明白为什么这应该如此难以实施。如果我错过了什么,欢迎大家纠正我:)


2
投票

我认为你可以在alloc init Label之后编写下面的代码

UILabel* lbl = [[UILabel alloc]initWithFrame:CGRectMake(0, 10, 280, 50)];
lbl.text = @"vbdsbfdshfisdhfidshufidhsufhdsf dhdsfhdksbf hfsdh fksdfidsf sdfhsd fhdsf sdhfh sdifsdkf ksdhfkds fhdsf dsfkdsfkjdhsfkjdhskfjhsdk fdhsf ";
[lbl setMinimumFontSize:8.0];
[lbl setNumberOfLines:0];
[lbl setFont:[UIFont systemFontOfSize:10.0]];
lbl.lineBreakMode = UILineBreakModeWordWrap;
lbl.backgroundColor = [UIColor redColor];
[lbl sizeToFit];
[self.view addSubview:lbl];

它正在与我合作使用它

© www.soinside.com 2019 - 2024. All rights reserved.