适应UILabel中的文本

38

这是我的代码

 UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(10, 50, 300, 50)];
    label.textAlignment = UITextAlignmentCenter;
    label.backgroundColor = [UIColor clearColor];
    label.textColor = [UIColor whiteColor];
    label.textColor.font = [UIFont fontWithName:@"Verdana" size:30];
    label.text = @"A very long string";
     etc...

问题是字体太大装不下标签,只显示"A very"。

应该怎么做才能让整个文本都显示出来呢? 我已经尝试过

label.lineBreakMode = UILineBreakModeWordWrap;
label.numberOfLines = 0;

但是这对我没有用。

我希望能够以编程的方式实现这个功能。

//编辑

CGRect frame = CGRectMake(10, 50, 300, 50);
    NSString *labelString = @"Players.";

    UILabel *howManyUsersLabel = [[UILabel alloc]initWithFrame:frame];
    howManyUsersLabel.textAlignment = UITextAlignmentCenter;
    howManyUsersLabel.backgroundColor = [UIColor clearColor];
    howManyUsersLabel.textColor = [UIColor whiteColor];
    howManyUsersLabel.adjustsFontSizeToFitWidth = NO;
    howManyUsersLabel.numberOfLines = 0;

    CGFloat fontSize = 30;
    while (fontSize > 0.0)
    {
        CGSize size = [labelString sizeWithFont:[UIFont fontWithName:@"Verdana" size:fontSize] constrainedToSize:CGSizeMake(frame.size.width, 10000) lineBreakMode:UILineBreakModeWordWrap];

        if (size.height <= frame.size.height) break;
        fontSize -= 1.0;
        NSLog(@"test");
    }

    howManyUsersLabel.font = [UIFont fontWithName:@"Verdana" size:fontSize];

1
唯一的两个选项是减小字体大小或扩大矩形大小。 - Michael Smith
是的,但我认为问题是如何在运行时计算正确的字体大小,如果您事先不知道文本将是什么。 - Nick Lockwood
7个回答

89

我认为你只需要添加这个:

label.adjustsFontSizeToFitWidth = YES;
label.minimumFontSize = 0;

那么文本将自动调整大小以适应标签。

需要注意的是,这只有在label.numberOfLines = 1时才能正常工作,这样文本才能显示在一行上。

如果需要文本换行并仍然缩小以适应标签,解决方案就更复杂了。要做到这一点,您需要计算文本的渲染大小,然后在循环中减小它,如下所示:

NSString *theText = @"A long string";
CGRect labelRect = CGRectMake(10, 50, 300, 50);
label.adjustsFontSizeToFitWidth = NO;
label.numberOfLines = 0;

CGFloat fontSize = 30;
while (fontSize > 0.0)
{
    CGSize size = [theText sizeWithFont:[UIFont fontWithName:@"Verdana" size:fontSize] constrainedToSize:CGSizeMake(labelRect.size.width, 10000) lineBreakMode:UILineBreakModeWordWrap];

    if (size.height <= labelRect.size.height) break;

    fontSize -= 1.0;
}

//set font size
label.font = [UIFont fontWithName:@"Verdana" size:fontSize];

这基本上只是通过减小字体大小来使其适应标签。

更新:

从iOS7开始,当adjustsFontSizeToFitWidth = YES时,多行文本也会自动缩小,因此不再需要此答案的第二部分(除非你仍然支持iOS6及更早版本)。


哦,我收到了“使用未声明的标识符constrainedToSize”的错误提示。 - objlv
抱歉,循环结束时请注意新的一行。我还在while(...)内部添加了一个安全检查。这会教训我匆忙编写代码的做法! - Nick Lockwood
请确保将linebreakmodewordwrap添加到标签中。如果仍然无法正常工作,请尝试在循环中放置一个size.height的NSLog,并检查它每次循环时是否下降。还要记录最终的textSize。如果为零,则表示出现了问题。 - Nick Lockwood
我在while循环的末尾添加了NSLog(@"test");,但输出中没有字符串“test”。由于某种原因,while语句未被执行。请查看更新后的代码。 - objlv
好的,我增加了labelString。现在在NSLog中输出“%@”时,我得到了null。 - objlv
显示剩余6条评论

3
最后我找到了解决阿拉伯语文本对齐问题的方法,你只需要按照以下方式操作:
    label.text = @"هذا هو نص طويل جدا";
    label.textAlignment = NSTextAlignmentNatural;

    CGSize size = [labels sizeThatFits:CGSizeMake(_lblAddress.width, CGFLOAT_MAX)];
    label.height = size.height;

1
[UILabel sizeToFit];

它将适用于您的问题。


1

使用iOS 9的Swift

let maxFontSize: CGFloat = 40
let minFontSize: CGFloat = 10

label.font = UIFont(name: label.font.fontName, size: maxFontSize)!
label.adjustsFontSizeToFitWidth = true
label.minimumScaleFactor = minFontSize/maxFontSize

这不会增加字体大小以填充标签。它只是从最大尺寸开始逐渐减小到最小尺寸,必要时进行调整。这也假设行数为1。

0
CGRect titleRect        = CGRectMake(10, 50, 300, 50);

UILabel *textTitleView  = [[UILabel alloc] initWithFrame:titleRect];

textTitleView.numberOfLines = 3  //for multiple lines;

textTitleView.lineBreakMode = UILineBreakModeWordWrap;

[UIFont fontWithName:@"Verdana" size:30];

textTitleView.text          = @"your text";

这并没有解决溢出的问题。 - i_am_jorf

0

iOS 8(可能也包括iOS 7)中似乎所有东西都出了问题。

解决方案:

-(UIFont*)fontForString:(NSString*)string toFitInRect:(CGRect)rect seedFont:(UIFont*)seedFont {
    UIFont* returnFont = seedFont;
    CGSize stringSize = [string sizeWithAttributes:@{NSFontAttributeName : seedFont}];

    while(stringSize.width > rect.size.width){
        returnFont = [UIFont systemFontOfSize:returnFont.pointSize -1];
        stringSize = [string sizeWithAttributes:@{NSFontAttributeName : returnFont}];
    }

    return returnFont;
}

请确保您不要尝试使用label.adjustsFontSizeToFitWidth = YES,否则它将变得非常混乱,新的大小将无法正常工作。

0

现在,Interface Builder可以让您这样做。

  1. 在UILabel下的Autoshrink中,选择"最小字体大小"而不是"固定字体大小"。
  2. 最小字体大小设置为合理的数值,例如8。
  3. 您还可以勾选"紧缩字母间距"复选框。

或者您也可以通过编程实现:

label.adjustsFontSizeToFitWidth = YES;

minimumFontSize在iOS 6中已被弃用 - 请改用minimumScaleFactor。 - brandonscript

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接