如何计算iOS 7中的实际字体大小(不是边界矩形)?

编辑:链接的“重复”问题只涉及计算文本矩形。 我需要计算标签缩放后的实际字体大小,而不是string大小。

此方法现在已被弃用:

size = [self sizeWithFont:font // 20 minFontSize:minFontSize // 14 actualFontSize:&actualFontSize // 16 forWidth:maxWidth lineBreakMode:self.lineBreakMode]; 

如何在iOS 7中缩小文本大小以适应UILabel的字体大小?

我有同样的问题,我需要知道实际的大小,使其他UILabels在我的UIView匹配。

我知道这不是一个完美的解决scheme,但也许对你有用。

我的解决scheme是:而不是使用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; 

从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; } 

我在我的应用程序中使用它来获取三个不同标签的字体大小,我需要保持大小同步,同时仍然允许它们自动缩小本地化的翻译,可以比原来的英语同行更长。

我为每个标签调用一次该方法,然后如果它们不是全部相同的值,我将标签的字体大小设置为三者中的最小值。

在iOS 6的UILabel以及iOS 7的NSStringgraphics添加中,不推荐使用minFontSize 。如果要使用它并查找使用的实际字体大小,则需要使用您在问题中提到的弃用方法。

minFontSize的replace是minimumScaleFactor 。 如果你想find使用的实际比例因子,你需要创build一个NSStringDrawingContext并在boundingRectWithSize:options:attributes:context: message中传递它,如下所示:

 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; 

扩大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 

Objective 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; } 

我的具体任务是调整sizeFontSizeToFitWidth启用的同时在两个标签上的字体大小。 该解决scheme适用于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]; } 

下一个代码不支持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; } 

单线UILabel的简单解决scheme:

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

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) } }