ios UILabel 不会自动收缩文本以适应标签大小

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9908334/
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 17:35:16  来源:igfitidea点击:

UILabel is not auto-shrinking text to fit label size

iphoneobjective-cioscocoa-touchipad

提问by Lukas

I have this strange issue, and im dealing with it for more than 8 hours now.. Depending on situation i have to calculate UILabelssize dynamically,
e.g
my UIViewControllerreceives an event and i change UILabelssize. from bigger to smaller. The size of my UILabelgets smaller and i get the correct needed size, but the text in my UILabelstays the same, the same font size and etc. I need the font to get smaller, for the whole text to fit the UILabel. So the question is how to make the text to fit my label with autoshrinkingor something like that?

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

In my xib, UILabelsautoshrinkis checked, also number of linesis set to 0, and also my string has new line symbols (\n), and i've selected linebreakmodeto wordwrap. Maybe anyone was in the same situation as i am now, and could help me? I would really appreciate that.

在我的xib,UILabelsautoshrink被选中,行数也设置为 0,我的字符串也有换行符 (\n),我选择了linebreakmodewordwrap. 也许有人和我现在的情况一样,可以帮助我吗?我真的很感激。

Thank's in advance!

提前致谢!

EDIT:UILabelminimum font size is set to 10

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

回答by lester

In case you are still searching for a better solution, I think this is what you want:

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

A Boolean value indicating whether the font size should be reduced in order to fit the title string into the label's bounding rectangle (this property is effective only when the numberOfLinesproperty is set to 1).

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

When setting this property, minimumScaleFactorMUST be set too (a good default is 0.5).

设置此属性时,也minimumScaleFactor必须设置(一个好的默认值是 0.5)。

Swift

迅速

var adjustsFontSizeToFitWidth: Bool { get set }

Objective-C

目标-C

@property(nonatomic) BOOL adjustsFontSizeToFitWidth;


A Boolean value indicating whether spacing between letters should be adjusted to fit the string within the label's bounds rectangle.

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

Swift

迅速

var allowsDefaultTighteningForTruncation: Bool { get set }

Objective-C

目标-C

@property(nonatomic) BOOL allowsDefaultTighteningForTruncation;

Source.

来源

回答by ohho

This is how I get UILabel Autoshrinkwork (especially for height of label font fitting in 4s device from 6s Plus Storyboard) in iOS 9.2, Xcode 7.2 ...

这就是我Autoshrink在 iOS 9.2、Xcode 7.2 中获得 UILabel工作的方式(特别是对于 6s Plus Storyboard 中 4s 设备中的标签字体高度)...

enter image description here

在此处输入图片说明

  • Number of lines is 0
  • Line Breaks: Clip
  • Autoshrink: Minimum Font Scale 0.25
  • 行数为 0
  • 换行符:剪辑
  • 自动收缩:最小字体比例 0.25

回答by Lukas

minimumFontSizeis deprecated in iOS 6.

minimumFontSize在 iOS 6 中已弃用。

So use minimumScaleFactorinstead of minmimumFontSize.

所以使用minimumScaleFactor代替minmimumFontSize.

lbl.adjustsFontSizeToFitWidth = YES
lbl.minimumScaleFactor = 0.5

Swift 5

斯威夫特 5

lbl.adjustsFontSizeToFitWidth = true
lbl.minimumScaleFactor = 0.5

回答by loki-e

also my solution is the boolean label.adjustsFontSizeToFitWidth = YES; BUT. You must in the interface Builder the Word Wrapping switch to "CLIP". Then autoshrink the Labels. This is very important.

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

回答by Naloiko Eugene

In Swift 3 (Programmatically) I had to do this:

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

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

回答by Birju

You can write like

你可以这样写

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];

You can calculate number of lines like that

你可以计算这样的行数

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";

Hope this will help you :-) waiting for your reply

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

回答by Kosta Eleftheriou

It's a great question, because it feels like that would be part of the built-in UIKitfunctionality or a related framework by now. Here's a good visual example of the question:

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

Font resizing animation

字体大小调整动画

There's no easy way around it, but it's definitely possible. One way to do this is to programmatically try different font sizes until you find one that fits reasonably close to the bounds of the view. You can accomplish this with the boundingRect()function of NSStringor NSAttributedString. For example:

没有简单的方法可以解决它,但这绝对是可能的。一种方法是以编程方式尝试不同的字体大小,直到找到适合视图边界的合适字体大小。您可以使用或的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

You can do a binary search to be more efficient than a complete brute force approach. There are also some considerations that are a bit more involved, including correct word wrapping and iOS font caching performance, if you're looking for something really robust.

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

If you only care about showing the text on the screen in an easy way, I have developed a robust implementation in Swift, which I'm also using in a production app. It's a UIViewsubclass with efficient, automatic font scaling for any input text, including multiple lines. To use it, you'd simply do something like:

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

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

That's it! You can find the complete source here: https://github.com/FlickType/AccessibilityKit

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

Hope this helps!

希望这可以帮助!

回答by Lukas

Well in the end i didn't find my answer. And i think the autoshrink doesn't work for multiple lines. I ended up using suggestion in this link: autoshrink on a UILabel with multiple lines

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

The solutions is to calulate text height at given width and if text is bigger, to shrink font size and then do he same again until the height is equal or less than your needed size.

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

I don't understand why this should be so hard to implement. If i'm missing something, everyone is welcome to correct me :)

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

回答by Rob Mcelvenny

This is for Swift 3 running Xcode 8.2.1 ( 8C1002 )

这是针对运行 Xcode 8.2.1 ( 8C1002 ) 的 Swift 3

The best solution that I've found is to set a fixed width in your Storyboard or IB on the label. Set your constraints with constrain to margins. In your viewDidLoad add the following lines of code:

我发现的最佳解决方案是在标签上的 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

属性检查器

This worked like a charm and it doesn't overflow to a new line and shrinks the text to fit the width of the label without any weird issues and works in Swift 3.

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

回答by Nick Yap

In iOS 9 I just had to:

在 iOS 9 中,我只需要:

  1. Add constraints from the left and right of the label to the superview.
  2. Set the line break mode to clipping in IB.
  3. Set the number of lines to 1 in IB.
  1. 将标签左右两侧的约束添加到超视图中。
  2. 将换行模式设置为 IB 中的剪辑。
  3. 将 IB 中的行数设置为 1。

Someone recommended setting number of lines to 0, but for me this just made the label go to multiple lines...

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