我目前有一个UILabel:

factLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 100, 280, 100)];
factLabel.text = @"some text some text some text some text";
factLabel.backgroundColor = [UIColor clearColor];
factLabel.lineBreakMode = UILineBreakModeWordWrap;
factLabel.numberOfLines = 10;
[self.view addSubview:factLabel];

在我的iOS应用程序的整个生命周期中,factLabel获得了许多不同的值。有的句子很多,有的只有5到6个单词。

我如何设置UILabel,使字体大小的变化,使文本总是适合我定义的界限?


当前回答

一行:

factLabel.numberOfLines = 1;
factLabel.minimumFontSize = 8;
factLabel.adjustsFontSizeToFitWidth = YES;

上面的代码将调整你的文本的字体大小(例如)8试图适合你的文本在标签。 numberolines = 1是必选项。

多行:

对于numberolines > 1,有一个方法可以通过NSString的sizeWithFont来计算最终文本的大小:…UIKit添加方法,例如:

CGSize lLabelSize = [yourText sizeWithFont:factLabel.font
                                  forWidth:factLabel.frame.size.width
                             lineBreakMode:factLabel.lineBreakMode];

之后,你可以使用产生的lLabelSize来调整你的标签大小,例如(假设你只会改变标签的高度):

factLabel.frame = CGRectMake(factLabel.frame.origin.x, factLabel.frame.origin.y, factLabel.frame.size.width, lLabelSize.height);

iOS6

一行:

从iOS6开始,minimumFontSize已弃用。这条线

factLabel.minimumFontSize = 8.;

可更改为:

factLabel.minimumScaleFactor = 8./factLabel.font.pointSize;

iOS7

多行:

从iOS7开始,sizeWithFont不再使用。 多行大小写简化为:

factLabel.numberOfLines = 0;
factLabel.lineBreakMode = NSLineBreakByWordWrapping;
CGSize maximumLabelSize = CGSizeMake(factLabel.frame.size.width, CGFLOAT_MAX);
CGSize expectSize = [factLabel sizeThatFits:maximumLabelSize];
factLabel.frame = CGRectMake(factLabel.frame.origin.x, factLabel.frame.origin.y, expectSize.width, expectSize.height);

iOS 13 (Swift 5):

label.adjustsFontSizeToFitWidth = true
label.minimumScaleFactor = 0.5

其他回答

根据@Eyal Ben Dov的回答,你可能想要创建一个类别,以便在你的其他应用中灵活使用。

奥林匹克广播服务公司。:我已经更新了他的代码,使其与iOS 7兼容

筒式水管文件

#import <UIKit/UIKit.h>

@interface UILabel (DynamicFontSize)

-(void) adjustFontSizeToFillItsContents;

@end

实现文件

#import "UILabel+DynamicFontSize.h"

@implementation UILabel (DynamicFontSize)

#define CATEGORY_DYNAMIC_FONT_SIZE_MAXIMUM_VALUE 35
#define CATEGORY_DYNAMIC_FONT_SIZE_MINIMUM_VALUE 3

-(void) adjustFontSizeToFillItsContents
{
    NSString* text = self.text;

    for (int i = CATEGORY_DYNAMIC_FONT_SIZE_MAXIMUM_VALUE; i>CATEGORY_DYNAMIC_FONT_SIZE_MINIMUM_VALUE; i--) {

        UIFont *font = [UIFont fontWithName:self.font.fontName size:(CGFloat)i];
        NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:text attributes:@{NSFontAttributeName: font}];

        CGRect rectSize = [attributedText boundingRectWithSize:CGSizeMake(self.frame.size.width, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin context:nil];

        if (rectSize.size.height <= self.frame.size.height) {
            self.font = [UIFont fontWithName:self.font.fontName size:(CGFloat)i];
            break;
        }
    }

}

@end

使用

#import "UILabel+DynamicFontSize.h"

[myUILabel adjustFontSizeToFillItsContents];

干杯

它有点不复杂,但这应该是可行的, 例如,假设你想把你的uilabel设置为120x120,最大字体大小为28:

magicLabel.numberOfLines = 0;
magicLabel.lineBreakMode = NSLineBreakByWordWrapping;
...
magicLabel.text = text;
    for (int i = 28; i>3; i--) {
        CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:(CGFloat)i] constrainedToSize:CGSizeMake(120.0f, CGFLOAT_MAX) lineBreakMode:NSLineBreakByWordWrapping];
        if (size.height < 120) {
            magicLabel.font = [UIFont systemFontOfSize:(CGFloat)i];
            break;
        }
    }

斯威夫特版本:

textLabel.adjustsFontSizeToFitWidth = true
textLabel.minimumScaleFactor = 0.5

这是一个快速扩展UILabel。它运行一个二进制搜索算法,根据标签边界的宽度和高度调整字体大小。测试工作与iOS 9和自动布局。

用法:<label>是预定义的需要调整字体大小的UILabel

<label>.fitFontForSize()

默认情况下,该函数在5pt和300pt的字体大小范围内搜索,并将字体设置为“完全”适合其文本的范围(精确到1.0pt)。你可以定义参数,这样,例如,它在1pt和标签当前字体大小之间精确搜索0.1pts,如下所示:

<label>.fitFontForSize(1.0, maxFontSize: <label>.font.pointSize, accuracy:0.1)

复制/粘贴以下代码到您的文件中

extension UILabel {

    func fitFontForSize(var minFontSize : CGFloat = 5.0, var maxFontSize : CGFloat = 300.0, accuracy : CGFloat = 1.0) {
        assert(maxFontSize > minFontSize)
        layoutIfNeeded() // Can be removed at your own discretion
        let constrainedSize = bounds.size
        while maxFontSize - minFontSize > accuracy {
            let midFontSize : CGFloat = ((minFontSize + maxFontSize) / 2)
            font = font.fontWithSize(midFontSize)
            sizeToFit()
            let checkSize : CGSize = bounds.size
            if  checkSize.height < constrainedSize.height && checkSize.width < constrainedSize.width {
                minFontSize = midFontSize
            } else {
                maxFontSize = midFontSize
            }
        }
        font = font.fontWithSize(minFontSize)
        sizeToFit()
        layoutIfNeeded() // Can be removed at your own discretion
    }

}

注意:每个layoutIfNeeded()调用都可以自行删除

Swift 2.0版本:

private func adapteSizeLabel(label: UILabel, sizeMax: CGFloat) {
     label.numberOfLines = 0
     label.lineBreakMode = NSLineBreakMode.ByWordWrapping
     let maximumLabelSize = CGSizeMake(label.frame.size.width, sizeMax);
     let expectSize = label.sizeThatFits(maximumLabelSize)
     label.frame = CGRectMake(label.frame.origin.x, label.frame.origin.y, expectSize.width, expectSize.height)
}