我有这个奇怪的问题,我已经处理了 8 个多小时了。根据情况我必须动态计算 UILabels
大小,
例如
我的 UIViewController
收到一个事件,我改变 { 1}大小。从大到小。我的 UILabel
的大小变小了,我得到了所需的正确大小,但我的 UILabel
中的文本保持不变,字体大小相同等等。我需要字体变小,以适应整个文本UILabel
。所以问题是如何使用 autoshrinking
或类似的东西使文本适合我的标签?
在我的 xib
中,UILabels
autoshrink
被选中,行数 设置为 0,我的字符串也有换行符 (\n),我选择了 < strong>linebreakmode 到 wordwrap
。也许有人和我现在的情况一样,可以帮助我吗?我真的很感激。
提前致谢!
编辑: UILabel
最小字体大小设置为 10
如果您仍在寻找更好的解决方案,我认为这就是您想要的:
一个布尔值,指示是否应减小字体大小以使标题字符串适合标签的边界矩形(此属性仅在 numberOfLines
属性设置为 1 时有效)。
设置此属性时,也必须设置 minimumScaleFactor
(一个好的默认值为 0.5)。
迅速
var adjustsFontSizeToFitWidth: Bool { get set }
Objective-C
@property(nonatomic) BOOL adjustsFontSizeToFitWidth;
一个布尔值,指示是否应调整字母之间的间距以适合标签边界矩形内的字符串。
迅速
var allowsDefaultTighteningForTruncation: Bool { get set }
Objective-C
@property(nonatomic) BOOL allowsDefaultTighteningForTruncation;
这就是我在 iOS 9.2、Xcode 7.2 中获得 UILabel Autoshrink
工作的方式(特别是对于 6s Plus Storyboard 的 4s 设备中的标签字体高度)...
https://i.stack.imgur.com/RtcVf.png
行数为 0
换行符:剪辑
自动收缩:最小字体比例 0.25
minimumFontSize
在 iOS 6 中已弃用。
所以使用 minimumScaleFactor
而不是 minmimumFontSize
。
lbl.adjustsFontSizeToFitWidth = YES
lbl.minimumScaleFactor = 0.5
斯威夫特 5
lbl.adjustsFontSizeToFitWidth = true
lbl.minimumScaleFactor = 0.5
我的解决方案也是 boolean label.adjustsFontSizeToFitWidth = YES;但。您必须在界面生成器中将自动换行切换到“CLIP”。然后自动收缩标签。这个非常重要。
在 Swift 3(以编程方式)中,我必须这样做:
let lbl = UILabel()
lbl.numberOfLines = 0
lbl.lineBreakMode = .byClipping
lbl.adjustsFontSizeToFitWidth = true
lbl.minimumScaleFactor = 0.5
lbl.font = UIFont.systemFont(ofSize: 15)
你可以这样写
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";
希望这会对您有所帮助:-) 等待您的回复
好吧,最后我没有找到我的答案。而且我认为自动收缩不适用于多行。我最终在此链接中使用了建议:autoshrink on a UILabel with multiple lines
解决方案是在给定宽度下计算文本高度,如果文本更大,则缩小字体大小,然后再次执行相同操作,直到高度等于或小于您需要的大小。
我不明白为什么这应该很难实现。如果我遗漏了什么,欢迎大家纠正我:)
这适用于运行 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
}
https://i.stack.imgur.com/kXhch.png
https://i.stack.imgur.com/EnTCx.png
https://i.stack.imgur.com/XTkfc.png
这就像一个魅力,它不会溢出到新行并且缩小文本以适应标签的宽度,没有任何奇怪的问题,并且可以在 Swift 3 中使用。
这是一个很好的问题,因为现在感觉这将是内置 UIKit
功能或相关框架的一部分。这是该问题的一个很好的视觉示例:
https://cdn-images-1.medium.com/max/1600/1*ycfVpMysgKuDgYkwKpuAhA.gif
没有简单的方法解决它,但它绝对是可能的。一种方法是以编程方式尝试不同的字体大小,直到找到适合接近视图边界的字体。您可以使用 NSString
或 NSAttributedString
的 boundingRect()
函数来完成此操作。例如:
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
您可以进行二分搜索,使其比完整的蛮力方法更有效。如果您正在寻找真正强大的东西,那么还有一些需要考虑的因素更多,包括正确的自动换行和 iOS 字体缓存性能。
如果您只关心以简单的方式在屏幕上显示文本,我已经在 Swift 中开发了一个强大的实现,我也在生产应用程序中使用它。它是一个 UIView
子类,可为任何输入文本(包括多行)提供高效、自动的字体缩放。要使用它,您只需执行以下操作:
let view = AKTextView()
// Use a simple or fancy NSAttributedString
view.attributedText = .init(string: "Some text here")
// Add to the view hierarchy somewhere
而已!您可以在此处找到完整的源代码:https://github.com/FlickType/AccessibilityKit
希望这可以帮助!
在 iOS 9 中,我只需要:
将标签左右的约束添加到superview。在 IB 中将换行模式设置为剪裁。在 IB 中将行数设置为 1。
有人建议将行数设置为 0,但对我来说,这只是让标签变为多行......
UILabel
和一个 UITextField
,然后单击了“解决自动布局问题”和“添加缺少的约束”。一切都排好了,但 Autoshrink 需要知道到标签的距离,“添加缺少的约束”没有为其添加约束。
我认为您可以在 alloc init Label 之后编写以下代码
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];
它很适合我使用它
两年过去了,这个问题仍然存在......
在 iOS 8 / XCode 6.1 中,我有时会发现我的 UILabel
(在 UITableViewCell
中创建,启用了 AutoLayout,并具有灵活的约束,因此它有足够的空间)不会自行调整大小以适应文本字符串。
与前几年一样,解决方案是设置文本,然后然后调用 sizeToFit
。
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
. . .
cell.lblCreatedAt.text = [note getCreatedDateAsString];
[cell.lblCreatedAt sizeToFit];
}
(叹。)
下面是如何做到这一点。假设以下 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.
如果 numberOfLines > 1
我所做的事情是这样的,则不起作用 -
if(lblRecLocation.text.length > 100)
lblRecLocation.font = [UIFont fontWithName:@"app_font_name" size:10];
在 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)
聚会迟到了,但由于我有每行一个单词的额外要求,所以这一添加对我有用:
label.numberOfLines = [labelString componentsSeparatedByString:@" "].count;
Apple Docs 说:
通常,标签文本是使用您在字体属性中指定的字体绘制的。但是,如果此属性设置为 YES,并且 text 属性中的文本超出标签的边界矩形,则接收器开始减小字体大小,直到字符串适合或达到最小字体大小。在 iOS 6 及更早版本中,该属性仅在 numberOfLines 属性设置为 1 时有效。
但这是一个谎言。我告诉你一个谎言!所有 iOS 版本都是如此。具体来说,当在 UICollectionViewCell
中使用 UILabel
时,情况确实如此,其大小由在运行时通过自定义布局动态调整的约束确定(例如 self.menuCollectionViewLayout.itemSize = size
)。
因此,当与 adjustsFontSizeToFitWidth
和 minimumScaleFactor
结合使用时,如前面的答案中所述,基于字数以编程方式设置 numberOfLines
解决了自动收缩问题。根据字数甚至字符数做类似的事情可能会产生“足够接近”的解决方案。
斯威夫特 4,Xcode 9.4.1
对我有用的解决方案:我在集合视图单元格中有一个标签,并且标签文本正在被修剪。在 Storyboard 上设置如下属性
Lines = 0
LineBreak = Word Wrap
Set yourlabel's leading and trailing constraint = 0 (using Autolayout)
minimumFontSize
在 iOS 6.0 中已弃用。请改用minimumScaleFactor
。