编辑:链接的“重复”问题仅涉及计算文本矩形。我需要在标签缩放后计算实际字体大小,而不是字符串大小。
现在不推荐使用此方法:
size = [self sizeWithFont:font // 20
minFontSize:minFontSize // 14
actualFontSize:&actualFontSize // 16
forWidth:maxWidth
lineBreakMode:self.lineBreakMode];
如何缩小适合的文本大小,在iOS 7中计算UILabel的字体大小?
答案 0 :(得分:11)
我遇到了同样的问题,我需要知道实际的大小才能使我的UIView中的其他UILabel匹配。
我知道这不是一个完美的解决方案,但也许对你有用。
我的解决方案是:而不是使用adjustsFontSizeToFitWidth
我计算“手动”大小。
CGSize initialSize = [_label.text sizeWithAttributes:@{NSFontAttributeName:_label.font}];
while ( initialSize.width > _label.frame.size.width ) {
[_label setFont:[_label.font fontWithSize:_label.font.pointSize - 1]];
initialSize = [_label.text sizeWithAttributes:@{NSFontAttributeName:_label.font}];
}
CGFloat actualSize = _label.font.pointSize;
答案 1 :(得分:9)
从Julius Bahr在本页面上的答案中提取,此方法非常适合在自动调整后获取实际字体大小:
- (CGFloat)getActualFontSizeForLabel:(UILabel *)label
{
NSStringDrawingContext *labelContext = [NSStringDrawingContext new];
labelContext.minimumScaleFactor = label.minimumScaleFactor;
NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:label.text attributes:@{ NSFontAttributeName: label.font }];
[attributedString boundingRectWithSize:label.frame.size
options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
context:labelContext];
CGFloat actualFontSize = label.font.pointSize * labelContext.actualScaleFactor;
return actualFontSize;
}
我在我的应用程序中使用它来获取三个不同标签的字体大小,我需要保持大小同步,同时仍然允许它们自动缩小以进行本地化翻译,这些翻译可能比原始版本长得多英语同行。
我为每个标签调用一次该方法,然后如果它们不是全部相同的值,我将标签的字体大小设置为三者中的最小值。
答案 2 :(得分:8)
在iOS 6中的minFontSize
以及iOS 7中的UILabel
绘图添加中,不推荐使用NSString
。如果您想使用它并查找使用的实际字体大小,您需要使用您在问题中提到的弃用方法。
minFontSize
的替换为minimumScaleFactor
。如果要查找使用的实际比例因子,则需要创建NSStringDrawingContext
并将其传递到boundingRectWithSize:options:attributes:context:
消息中,如下所示:
NSStringDrawingContext *context = [[NSStringDrawingContext alloc] init];
context.minimumScaleFactor = 0.7;
[label.text boundingRectWithSize:CGSizeMake(maxWidth, HUGE_VAL)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:@{
NSFontAttributeName: font
} context:context];
CGFloat actualFontSize = font.pointSize * context.actualScaleFactor;
答案 3 :(得分:5)
扩展Ferran的回答
要展开以填充宽度或高度,无论它首先击中
Swift版
func getFontSizeToFitFrameOfLabel(label: UILabel) -> CGFloat
{
var initialSize : CGSize = label.text!.sizeWithAttributes([NSFontAttributeName : label.font])
if initialSize.width > label.frame.size.width ||
initialSize.height > label.frame.size.height
{
while initialSize.width > label.frame.size.width ||
initialSize.height > label.frame.size.height
{
label.font = label.font.fontWithSize(label.font.pointSize - 1)
initialSize = label.text!.sizeWithAttributes([NSFontAttributeName : label.font])
}
} else {
while initialSize.width < label.frame.size.width &&
initialSize.height < label.frame.size.height
{
label.font = label.font.fontWithSize(label.font.pointSize + 1)
initialSize = label.text!.sizeWithAttributes([NSFontAttributeName : label.font])
}
// went 1 point too large so compensate here
label.font = label.font.fontWithSize(label.font.pointSize - 1)
}
return label.font.pointSize;
}
然后做这样的事情来使用它(比如你的标签叫做title1Label)
title1Label.frame = CGRect(x: 0.0, y: 0.0, width: view.frame.size.width, height: view.frame.size.height)
// sets font to some nonzero size to begin with, it will change up or down to fit the label's frame
title1Label.font = UIFont(name: "Super Mario 256", size: 45.0)
title1Label.font = title1Label.font.fontWithSize(getFontSizeToFitFrameOfLabel(title1Label))
// resize height to be a little larger than the font height
title1Label.frame.size.height = title1Label.font.pointSize*1.3
目标C版:
- (CGFloat) maxFontSize:(UILabel *)label{
CGSize initialSize = [label.text sizeWithAttributes:@{NSFontAttributeName:label.font}];
if (initialSize.width > label.frame.size.width ||
initialSize.height > label.frame.size.height)
{
while (initialSize.width > label.frame.size.width ||
initialSize.height > label.frame.size.height)
{
[label setFont:[label.font fontWithSize:label.font.pointSize - 1]];
initialSize = [label.text sizeWithAttributes:@{NSFontAttributeName:label.font}];
}
} else {
while (initialSize.width < label.frame.size.width &&
initialSize.height < label.frame.size.height)
{
[label setFont:[label.font fontWithSize:label.font.pointSize + 1]];
initialSize = [label.text sizeWithAttributes:@{NSFontAttributeName:label.font}];
}
// went 1 point too large so compensate here
[label setFont:[label.font fontWithSize:label.font.pointSize - 1]];
}
return label.font.pointSize;
}
答案 4 :(得分:4)
我的具体任务是在启用了adjustsFontSizeToFitWidth的情况下,同等地调整2个标签上的字体大小。 该解决方案适用于iOS 6和7。
+ (void)sizeLabelFontToMinSizeFor:(UILabel *)label1 and:(UILabel *)label2 {
NSStringDrawingContext *labelContext = [NSStringDrawingContext new];
labelContext.minimumScaleFactor = label1.minimumScaleFactor;
NSAttributedString *attributedString1 = [[NSAttributedString alloc] initWithString:label1.text attributes:@{NSFontAttributeName : label1.font}];
// the NSStringDrawingUsesLineFragmentOrigin and NSStringDrawingUsesFontLeading options are magic
[attributedString1 boundingRectWithSize:label1.frame.size options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading context:labelContext];
CGFloat actualFontSize1 = label1.font.pointSize * labelContext.actualScaleFactor;
labelContext = [NSStringDrawingContext new];
labelContext.minimumScaleFactor = label2.minimumScaleFactor;
NSAttributedString *attributedString2 = [[NSAttributedString alloc] initWithString:label2.text attributes:@{NSFontAttributeName : label2.font}];
[attributedString2 boundingRectWithSize:label2.frame.size options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading context:labelContext];
CGFloat actualFontSize2 = label2.font.pointSize * labelContext.actualScaleFactor;
CGFloat minSize = MIN(actualFontSize1, actualFontSize2);
label1.font = [UIFont fontWithName:RCDefaultFontName size:minSize];
label2.font = [UIFont fontWithName:RCDefaultFontName size:minSize];
}
答案 5 :(得分:2)
下一个代码不支持minFontSize和lineBreakMode,所以如果你需要它们,你应该自己改进它:
CGSize NSString_sizeWithFont(NSString * str, UIFont *font) {
CGSize result;
if (NO == [str respondsToSelector: @selector(sizeWithAttributes:)]) {
// legacy way
result = [str sizeWithFont: font];
} else {
// modern way
NSDictionary * dict = [NSDictionary dictionaryWithObjectsAndKeys:
font, NSFontAttributeName, nil];
result = [str sizeWithAttributes: dict];
}
return result;
}
UIFont * NSString_calcActualFont(NSString * str, UIFont * initialFont,
CGSize sizeLimit, CGSize * actualSize)
{
const CGSize curSize = NSString_sizeWithFont(str, initialFont);
CGFloat actualFontSize = initialFont.pointSize;
actualFontSize *= MIN(sizeLimit.width / curSize.width, sizeLimit.height / curSize.height);
UIFont * actualFont = [initialFont fontWithSize: floorf(actualFontSize)];
*actualSize = NSString_sizeWithFont(str, actualFont);
return actualFont;
}
答案 6 :(得分:0)
单线UILabel的简单解决方案:
//myLabel - initial label
UILabel *fullSizeLabel = [UILabel new];
fullSizeLabel.font = myLabel.font;
fullSizeLabel.text = myLabel.text;
[fullSizeLabel sizeToFit];
CGFloat actualFontSize = myLabel.font.pointSize * (myLabel.bounds.size.width / fullSizeLabel.bounds.size.width);
//correct, if new font size bigger than initial
actualFontSize = actualFontSize < myLabel.font.pointSize ? actualFontSize : myLabel.font.pointSize;
答案 7 :(得分:-1)
Erik van der Neut的代码对我有用,所以我将它翻译成Swift并将其包装在UILabel扩展中:
extension UILabel {
public func actualFontSize()-> CGFloat {
let context = NSStringDrawingContext()
context.minimumScaleFactor = self.minimumScaleFactor
let attributedString = NSAttributedString(string: self.text ?? "", attributes: [NSFontAttributeName: self.font])
attributedString.boundingRectWithSize(self.frame.size, options: [.UsesLineFragmentOrigin], context: context)
return (self.font.pointSize * context.actualScaleFactor)
}
}