ios 动态改变 UILabel 的字体大小

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4865458/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 18:44:42  来源:igfitidea点击:

Dynamically changing font size of UILabel

iosobjective-cfontsuilabel

提问by CodeGuy

I currently have a UILabel:

我目前有一个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];

Throughout the life of my iOS application, factLabelgets a bunch of different values. Some with multiple sentences, others with just 5 or 6 words.

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

How can I set up the UILabelso that the font size changes so that the text always fits in the bounds I defined?

如何设置UILabel以便改变字体大小以便文本始终适合我定义的边界?

回答by Martin Babacaev

Single line:

单线:

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

The above code will adjust your text's font size down to (for example) 8trying to fit your text within the label. numberOfLines = 1is mandatory.

上面的代码会将您的文本字体大小调整为(例如)8尝试使您的文本适合标签。 numberOfLines = 1是强制性的。

Multiple lines:

多行:

For numberOfLines > 1there is a method to figure out the size of final text through NSString's sizeWithFont:... UIKit additionmethods, for example:

因为numberOfLines > 1有一种方法可以通过NSString 的 sizeWithFont:... UIKit 添加方法来计算最终文本的大小,例如:

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

After that you can just resize your label using resulting lLabelSize, for example (assuming that you will change only label's height):

之后,您可以使用 result 调整标签大小lLabelSize,例如(假设您将仅更改标签的高度):

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

iOS6

iOS6

Single line:

单线:

Starting with iOS6, minimumFontSizehas been deprecated. The line

从 iOS6 开始,minimumFontSize已弃用。线

factLabel.minimumFontSize = 8.;

can be changed to:

可以改为:

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

iOS7

IOS 7

Multiple lines:

多行:

Starting with iOS7, sizeWithFontbecomes deprecated. Multiline case is reduced to:

从 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):

iOS 13 (Swift 5):

label.adjustsFontSizeToFitWidth = true
label.minimumScaleFactor = 0.5

回答by Amit Singh

minimumFontSizehas been deprecated with iOS 6. You can use minimumScaleFactor.

minimumFontSize已在 iOS 6 中弃用。您可以使用minimumScaleFactor.

yourLabel.adjustsFontSizeToFitWidth=YES;
yourLabel.minimumScaleFactor=0.5;

This will take care of your font size according width of label and text.

这将根据标签和文本的宽度处理您的字体大小。

回答by Paulo Miguel Almeida

Based on @Eyal Ben Dov's answer you may want to create a category to make it flexible to use within another apps of yours.

根据@Eyal Ben Dov 的回答,您可能希望创建一个类别,使其灵活地在您的其他应用程序中使用。

Obs.: I've updated his code to make compatible with iOS 7

观察:我已经更新了他的代码以与 iOS 7 兼容

-Header file

- 头文件

#import <UIKit/UIKit.h>

@interface UILabel (DynamicFontSize)

-(void) adjustFontSizeToFillItsContents;

@end

-Implementation file

-实施文件

#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

-Usage

-用法

#import "UILabel+DynamicFontSize.h"

[myUILabel adjustFontSizeToFillItsContents];

Cheers

干杯

回答by Devendra Singh

Single line- There are two ways, you can simply change.

单行- 有两种方式,您可以简单地更改。

1- Pragmatically (Swift 3)

1- 务实(Swift 3)

Just add the following code

只需添加以下代码

    yourLabel.numberOfLines = 1;
    yourLabel.minimumScaleFactor = 0.7;
    yourLabel.adjustsFontSizeToFitWidth = true;

2 - Using UILabel Attributes inspector

2 - 使用 UILabel 属性检查器

i- Select your label- Set number of lines 1.
ii- Autoshrink-  Select Minimum Font Scale from drop down
iii- Set Minimum Font Scale value as you wish , I have set 0.7 as in below image. (default is 0.5)

enter image description here

在此处输入图片说明

回答by zavtra

It's 2015. I had to go to find a blog post that would explain how to do it for the latest version of iOS and XCode with Swift so that it would work with multiple lines.

现在是 2015 年。我不得不去找一篇博客文章来解释如何使用 Swift 为最新版本的 iOS 和 XCode 执行此操作,以便它可以处理多行。

  1. set “Autoshrink” to “Minimum font size.”
  2. set the font to the largest desirable font size (I chose 20)
  3. Change “Line Breaks” from “Word Wrap” to “Truncate Tail.”
  1. 将“自动收缩”设置为“最小字体大小”。
  2. 将字体设置为所需的最大字体大小(我选择了 20)
  3. 将“换行符”从“自动换行”更改为“截尾”。

Source: http://beckyhansmeyer.com/2015/04/09/autoshrinking-text-in-a-multiline-uilabel/

资料来源:http: //beckyhansmeyer.com/2015/04/09/autoshrinking-text-in-a-multiline-uilabel/

回答by Esqarrouth

Swift version:

迅捷版:

textLabel.adjustsFontSizeToFitWidth = true
textLabel.minimumScaleFactor = 0.5

回答by Avi Frankl

Here's a Swift extension for UILabel. It runs a binary search algorithm to resize the font based off the width and height of the label's bounds. Tested to work with iOS 9 and autolayout.

这是 UILabel 的 Swift 扩展。它运行二进制搜索算法,根据标签边界的宽度和高度调整字体大小。经测试可与 iOS 9 和自动布局配合使用。

USAGE:Where <label>is your pre-defined UILabel that needs font resizing

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

<label>.fitFontForSize()

By Default, this function searches in within the range of 5pt and 300pt font sizes and sets the font to fit its text "perfectly" within the bounds (accurate within 1.0pt). You could define the parameters so that it, for example, searches between 1ptand the label's current font sizeaccurately within 0.1ptsin the following way:

默认情况下,此功能在 5pt 和 300pt 字体大小范围内搜索,并将字体设置为“完美”地适合其文本在边界内(精确到 1.0pt)。你可以定义参数,使得它,例如,搜索之间的1点标签的当前字体大小精确内0.1pts以下列方式:

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

Copy/Paste the following code into your file

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

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
    }

}

NOTE:Each of the layoutIfNeeded()calls can be removed at your own discretion

注意:layoutIfNeeded()您可以自行决定删除每个呼叫

回答by Eyal Ben Dov

Its a little bit not sophisticated but this should work, for example lets say you want to cap your uilabel to 120x120, with max font size of 28:

它有点不复杂,但这应该可以工作,例如,假设您想将 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;
        }
    }

回答by codercat

Just send the sizeToFit message to the UITextView. It will adjust its own height to just fit its text. It will not change its own width or origin.

只需将 sizeToFit 消息发送到 UITextView。它将调整自己的高度以适合其文本。它不会改变自己的宽度或原点。

[textViewA1 sizeToFit];

回答by Phil

Swift 2.0 Version:

斯威夫特 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)
}