如何根据标签可用的高度调整 UILabel 字体大小
Posted
技术标签:
【中文标题】如何根据标签可用的高度调整 UILabel 字体大小【英文标题】:How to adjust a UILabel font size based on the height available to the label 【发布时间】:2015-08-02 02:28:58 【问题描述】:我正在使用 UILables 的自动布局和文本大小调整,它在宽度上工作得很好,但在高度上却没有那么多。
如果宽度上的文本有空间但高度上没有空间,则文本不会压缩
任何想法如何创建约束来做到这一点?或者这是不可能的,我怎样才能找到适合矩形的最小文本大小?
【问题讨论】:
【参考方案1】:您可以将字体设置为自动填充标签的大小,并且可以选择不低于最小字体大小。只需将adjustsFontSizeToFitWidth 设置为YES。如果您需要更多信息,请查看UILabel Class Reference。
虽然布尔值称为“adjustsFontSizeToWidth”,但它实际上表示标签高度的最大尺寸,它将保留在标签的一行(或您指定的多行)上。
子类化 UILabel 并覆盖 layoutSubviews。然后每次 UILabel 改变其大小时,都会重新计算字体大小:
import Foundation
import UIKit
class LabelWithAdaptiveTextHeight: UILabel
override func layoutSubviews()
super.layoutSubviews()
font = fontToFitHeight()
// Returns an UIFont that fits the new label's height.
private func fontToFitHeight() -> UIFont
var minFontSize: CGFloat = DISPLAY_FONT_MINIMUM // CGFloat 18
var maxFontSize: CGFloat = DISPLAY_FONT_BIG // CGFloat 67
var fontSizeAverage: CGFloat = 0
var textAndLabelHeightDiff: CGFloat = 0
while (minFontSize <= maxFontSize)
fontSizeAverage = minFontSize + (maxFontSize - minFontSize) / 2
if let labelText: NSString = text
let labelHeight = frame.size.height
let testStringHeight = labelText.sizeWithAttributes(
[NSFontAttributeName: font.fontWithSize(fontSizeAverage)]
).height
textAndLabelHeightDiff = labelHeight - testStringHeight
if (fontSizeAverage == minFontSize || fontSizeAverage == maxFontSize)
if (textAndLabelHeightDiff < 0)
return font.fontWithSize(fontSizeAverage - 1)
return font.fontWithSize(fontSizeAverage)
if (textAndLabelHeightDiff < 0)
maxFontSize = fontSizeAverage - 1
else if (textAndLabelHeightDiff > 0)
minFontSize = fontSizeAverage + 1
else
return font.fontWithSize(fontSizeAverage)
return font.fontWithSize(fontSizeAverage)
【讨论】:
我一直在尝试 adjustsFontSizeToFitWidth 不工作正在剪切文本的顶部 我现在不在 Mac 上,我必须等到今晚才能测试它! :/ 但我会告诉你的。【参考方案2】:Swift 3.0 适合任何新来这里的人。
非常感谢@tymac 的原始答案。
真正帮助我在使我的应用程序通用时不必担心文本大小。
import UIKit
import Foundation
class LabelWithAdaptiveTextHeight: UILabel
override func layoutSubviews()
super.layoutSubviews()
font = fontToFitHeight()
// Returns an UIFont that fits the new label's height.
private func fontToFitHeight() -> UIFont
var minFontSize: CGFloat = 20
var maxFontSize: CGFloat = 250
var fontSizeAverage: CGFloat = 0
var textAndLabelHeightDiff: CGFloat = 0
while (minFontSize <= maxFontSize)
fontSizeAverage = minFontSize + (maxFontSize - minFontSize) / 2
if let labelText: String = text
let labelHeight = frame.size.height
let testStringHeight = labelText.size(attributes: [NSFontAttributeName: font.withSize(fontSizeAverage)]).height
textAndLabelHeightDiff = labelHeight - testStringHeight
if (fontSizeAverage == minFontSize || fontSizeAverage == maxFontSize)
if (textAndLabelHeightDiff < 0)
return font.withSize(fontSizeAverage - 1)
return font.withSize(fontSizeAverage)
if (textAndLabelHeightDiff < 0)
maxFontSize = fontSizeAverage - 1
else if (textAndLabelHeightDiff > 0)
minFontSize = fontSizeAverage + 1
else
return font.withSize(fontSizeAverage)
return font.withSize(fontSizeAverage)
【讨论】:
令人惊讶的是,这不是像“adjustFontSizeToFitHeight”这样的标准功能 太棒了!对 Swift 5 稍作调整:let testStringHeight = labelText.size(withAttributes: [NSAttributedString.Key.font: font.withSize(fontSizeAverage)]).height
...如果您想将最大字体大小保持在您在界面生成器中设置的字体大小,您可以将 maxFontSize 调整为var maxFontSize: CGFloat = font.pointSize
【参考方案3】:
对于任何感兴趣的人,这里是 tymac 的答案的 Objective-C 实现。
(我有点着急,没有时间修复小写 Gs、Js、Ps 和 Qs 被剪切,所以我迅速从计算函数中的平均文本大小中减去了两个,对不起。)
#import "LabelWithAdaptiveTextHeight.h"
#define DISPLAY_FONT_MINIMUM 6
#define DISPLAY_FONT_MAXIMUM 50
@interface LabelWithAdaptiveTextHeight ()
@end
@implementation LabelWithAdaptiveTextHeight
- (UIFont*)fontToFitHeight
float minimumFontSize = DISPLAY_FONT_MINIMUM;
float maximumFontSize = DISPLAY_FONT_MAXIMUM;
float fontSizeAverage = 0;
float textAndLabelHeightDifference = 0;
while(minimumFontSize <= maximumFontSize)
fontSizeAverage = minimumFontSize + (maximumFontSize - minimumFontSize) / 2;
if(self.text)
float labelHeight = self.frame.size.height;
float testStringHeight = [self.text sizeWithAttributes:@
NSFontAttributeName: [self.font fontWithSize:fontSizeAverage]
].height;
textAndLabelHeightDifference = labelHeight - testStringHeight;
if(fontSizeAverage == minimumFontSize || fontSizeAverage == maximumFontSize)
return [self.font fontWithSize:fontSizeAverage- (textAndLabelHeightDifference < 0)];
if(textAndLabelHeightDifference < 0)
maximumFontSize = fontSizeAverage - 1;
else if(textAndLabelHeightDifference > 0)
minimumFontSize = fontSizeAverage + 1;
else
return [self.font fontWithSize:fontSizeAverage];
else
break; //Prevent infinite loop
return [self.font fontWithSize:fontSizeAverage-2];
- (void)layoutSubviews
[super layoutSubviews];
self.font = [self fontToFitHeight];
@end
【讨论】:
以上是关于如何根据标签可用的高度调整 UILabel 字体大小的主要内容,如果未能解决你的问题,请参考以下文章