我目前有一个 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
以尝试使您的文本适合标签内。 numberOfLines = 1
是强制性的。
多行:
对于 numberOfLines > 1
,有一种方法可以通过 NSString's sizeWithFont:... UIKit addition 方法确定最终文本的大小,例如:
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;
IOS 7
多行:
从 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(斯威夫特 5):
label.adjustsFontSizeToFitWidth = true
label.minimumScaleFactor = 0.5
minimumFontSize
已在 iOS 6 中弃用。您可以使用 minimumScaleFactor
。
yourLabel.adjustsFontSizeToFitWidth=YES;
yourLabel.minimumScaleFactor=0.5;
这将根据标签和文本的宽度处理您的字体大小。
adjustsFontSizeToFitWidth
仅在不适合容器的情况下减少文本
单行 - 有两种方法,您可以简单地更改。
1-务实(Swift 3)
只需添加以下代码
yourLabel.numberOfLines = 1;
yourLabel.minimumScaleFactor = 0.7;
yourLabel.adjustsFontSizeToFitWidth = true;
- 使用 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)
https://i.stack.imgur.com/rCv5z.png
根据@Eyal Ben Dov 的回答,您可能希望创建一个类别以使其灵活地在您的其他应用程序中使用。
Obs.: 我已经更新了他的代码以兼容 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];
干杯
setNeedsLayout
/layoutIfNeeded
)。
现在是 2015 年。我不得不去找一篇博文,解释如何使用 Swift 为最新版本的 iOS 和 XCode 执行此操作,以便它可以处理多行。
将“自动缩小”设置为“最小字体大小”。将字体设置为所需的最大字体大小(我选择了 20)将“换行符”从“自动换行”更改为“截断尾巴”。
来源:http://beckyhansmeyer.com/2015/04/09/autoshrinking-text-in-a-multiline-uilabel/
斯威夫特版本:
textLabel.adjustsFontSizeToFitWidth = true
textLabel.minimumScaleFactor = 0.5
这是 UILabel 的 Swift 扩展。它运行二进制搜索算法来根据标签边界的宽度和高度调整字体大小。经测试可与 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()
调用
它有点不复杂,但这应该可以工作,例如,假设你想将你的 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;
}
}
只需将 sizeToFit 消息发送到 UITextView。它将调整自己的高度以适合其文本。它不会改变自己的宽度或原点。
[textViewA1 sizeToFit];
sizeToFit
后,您的 textViewA1
变为 200 个点,最终被裁剪。
斯威夫特 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)
}
此解决方案适用于多行:
在阅读了几篇文章之后,需要一个可以自动缩放文本并调整行数以最适合给定标签大小的函数,我自己编写了一个函数。 (即,短字符串会很好地放在一行上并使用大量标签框,而长字符串会自动拆分为 2 或 3 行并相应地调整大小)
随意重复使用它并根据需要进行调整。确保在 viewDidLayoutSubviews
完成后调用它,以便设置初始标签框架。
+ (void)setFontForLabel:(UILabel *)label withMaximumFontSize:(float)maxFontSize andMaximumLines:(int)maxLines {
int numLines = 1;
float fontSize = maxFontSize;
CGSize textSize; // The size of the text
CGSize frameSize; // The size of the frame of the label
CGSize unrestrictedFrameSize; // The size the text would be if it were not restricted by the label height
CGRect originalLabelFrame = label.frame;
frameSize = label.frame.size;
textSize = [label.text sizeWithAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize: fontSize]}];
// Work out the number of lines that will need to fit the text in snug
while (((textSize.width / numLines) / (textSize.height * numLines) > frameSize.width / frameSize.height) && (numLines < maxLines)) {
numLines++;
}
label.numberOfLines = numLines;
// Get the current text size
label.font = [UIFont systemFontOfSize:fontSize];
textSize = [label.text boundingRectWithSize:CGSizeMake(frameSize.width, CGFLOAT_MAX)
options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
attributes:@{NSFontAttributeName : label.font}
context:nil].size;
// Adjust the frame size so that it can fit text on more lines
// so that we do not end up with truncated text
label.frame = CGRectMake(label.frame.origin.x, label.frame.origin.y, label.frame.size.width, label.frame.size.width);
// Get the size of the text as it would fit into the extended label size
unrestrictedFrameSize = [label textRectForBounds:CGRectMake(0, 0, label.bounds.size.width, CGFLOAT_MAX) limitedToNumberOfLines:numLines].size;
// Keep reducing the font size until it fits
while (textSize.width > unrestrictedFrameSize.width || textSize.height > frameSize.height) {
fontSize--;
label.font = [UIFont systemFontOfSize:fontSize];
textSize = [label.text boundingRectWithSize:CGSizeMake(frameSize.width, CGFLOAT_MAX)
options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
attributes:@{NSFontAttributeName : label.font}
context:nil].size;
unrestrictedFrameSize = [label textRectForBounds:CGRectMake(0, 0, label.bounds.size.width, CGFLOAT_MAX) limitedToNumberOfLines:numLines].size;
}
// Set the label frame size back to original
label.frame = originalLabelFrame;
}
这是实现动画字体大小更改的 UILabel 子类的填充代码:
@interface SNTextLayer : CATextLayer
@end
@implementation SNTextLayer
- (void)drawInContext:(CGContextRef)ctx {
// We override this to make text appear at the same vertical positon as in UILabel
// (otherwise it's shifted tdown)
CGFloat height = self.bounds.size.height;
float fontSize = self.fontSize;
// May need to adjust this somewhat if it's not aligned perfectly in your implementation
float yDiff = (height-fontSize)/2 - fontSize/10;
CGContextSaveGState(ctx);
CGContextTranslateCTM(ctx, 0.0, yDiff);
[super drawInContext:ctx];
CGContextRestoreGState(ctx);
}
@end
@interface SNAnimatableLabel ()
@property CATextLayer* textLayer;
@end
@interface SNAnimatableLabel : UILabel
- (void)animateFontToSize:(CGFloat)fontSize withDuration:(double)duration;
@end
@implementation SNAnimatableLabel
- (void)awakeFromNib {
[super awakeFromNib];
_textLayer = [SNTextLayer new];
_textLayer.backgroundColor = self.backgroundColor.CGColor;
_textLayer.foregroundColor = self.textColor.CGColor;
_textLayer.font = CGFontCreateWithFontName((CFStringRef)self.font.fontName);
_textLayer.frame = self.bounds;
_textLayer.string = self.text;
_textLayer.fontSize = self.font.pointSize;
_textLayer.contentsScale = [UIScreen mainScreen].scale;
[_textLayer setPosition: CGPointMake(CGRectGetMidX(_textLayer.frame), CGRectGetMidY(_textLayer.frame))];
[_textLayer setAnchorPoint: CGPointMake(0.5, 0.5)];
[_textLayer setAlignmentMode: kCAAlignmentCenter];
self.textColor = self.backgroundColor;
// Blend text with background, so that it doens't interfere with textlayer text
[self.layer addSublayer:_textLayer];
self.layer.masksToBounds = NO;
}
- (void)setText:(NSString *)text {
_textLayer.string = text;
super.text = text;
}
- (void)layoutSubviews {
[super layoutSubviews];
// Need to enlarge the frame, otherwise the text may get clipped for bigger font sizes
_textLayer.frame = CGRectInset(self.bounds, -5, -5);
}
- (void)animateFontToSize:(CGFloat)fontSize withDuration:(double)duration {
[CATransaction begin];
[CATransaction setAnimationDuration:duration];
_textLayer.fontSize = fontSize;
[CATransaction commit];
}
sizeWithFont:constrainedToSize:lineBreakMode:
但是这种方式有点困难myLabel.minimumScaleFactor:10.0/[UIFont labelFontSize];