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

时间:2012-03-28 13:16:49

标签: iphone objective-c ios cocoa-touch ipad

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

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

提前感谢!

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

17 个答案:

答案 0 :(得分:149)

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

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

@property(nonatomic) BOOL adjustsFontSizeToFitWidth

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

@property(nonatomic) BOOL adjustsLetterSpacingToFitWidth

Source

答案 1 :(得分:112)

这就是我在iOS 9.2,Xcode 7.2中让UILabel Autoshrink工作的方式(尤其是4s设备中标签字体的高度,来自6s Plus Storyboard)......

enter image description here

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

答案 2 :(得分:66)

iOS 6中不推荐使用

minimumFontSize

因此请使用minimumScaleFactor代替minmimumFontSize

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

答案 3 :(得分:19)

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

答案 4 :(得分:6)

在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 :(得分: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";

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

答案 6 :(得分: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中工作。

答案 7 :(得分:3)

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

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

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

答案 8 :(得分:2)

我认为您可以在分配init标签

之后编写以下代码
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];

正在与我合作使用

答案 9 :(得分:2)

在iOS 9中,我只需要:

  1. 从标签的左侧和右侧添加约束到超级视图。
  2. 将换行模式设置为IB中的裁剪。
  3. 在IB中将行数设置为1.
  4. 有人建议将行数设置为0,但对我来说这只是让标签转到多行......

答案 10 :(得分: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];
}

(叹气。)

答案 11 :(得分:1)

如果numberOfLines > 1

不起作用 我做了什么造成了这样的条件 -

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

答案 12 :(得分: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.

答案 13 :(得分: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)

答案 14 :(得分:1)

这是一个很好的问题,因为到目前为止,这似乎已成为内置UIKit功能或相关框架的一部分。这是一个很好的视觉问题示例:

Font resizing animation

没有简单的解决方法,但是绝对有可能。一种方法是以编程方式尝试使用不同的字体大小,直到找到与视图边界相当接近的字体大小为止。您可以使用boundingRect()NSString的{​​{1}}函数来完成此操作。例如:

NSAttributedString

您可以执行二进制搜索,比完全的暴力破解方法更有效。如果您正在寻找真正强大的功能,那么还有一些需要更多考虑的因素,包括正确的自动换行和iOS字体缓存性能。

如果您只想以简单的方式在屏幕上显示文本,那么我已经在Swift中开发了一个可靠的实现,我还在生产应用程序中使用了该实现。这是一个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 子类,可对任何输入文本(包括多行)进行高效,自动的字体缩放。要使用它,您只需执行以下操作即可:

UIView

就是这样!您可以在此处找到完整的源代码:https://github.com/FlickType/AccessibilityKit

希望这会有所帮助!

答案 15 :(得分:0)

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

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

Apple Docs说:

  

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

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

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

答案 16 :(得分:0)

Swift 4,Xcode 9.4.1

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

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