¿Cómo calcular el tamaño real del punto de fuente en iOS 7 (no el rectángulo delimitador)?

Editar: la pregunta "duplicada" vinculada solo se refiere al cálculo del rectángulo de text. Necesito calcular el tamaño real de la fuente después de la escala de la label, NO el tamaño de la cadena.

Este método ahora está en desuso:

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

¿Cómo puedo calcular el tamaño de fuente de un UILabel ahora en iOS 7 cuando networkinguce el tamaño del text para que encaje?

Tengo el mismo problema, necesito saber el tamaño real para hacer que los otros UILabels en mi UIView coincidan.

Sé que no es una solución perfecta, pero quizás sea útil para ti.

Mi solución es: en lugar de utilizar adjustsFontSizeToFitWidth calculo "manualmente" el tamaño.

 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; 

Destilado de la respuesta de Julius Bahr en esta página, este método funciona perfectamente para get el tamaño de fuente real después de que se haya ajustado automáticamente:

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

Estoy usando esto en mi aplicación para get los tamaños de fuente para tres tags diferentes, para lo cual necesito mantener los tamaños sincronizados y, al mismo time, permitir que se encojan automáticamente para traducciones localizadas que pueden ser un poco más largas que sus homólogos ingleses originales.

Llamo a ese método una vez para cada label, y luego, si no son todos del mismo valor, establezco el tamaño de fuente de la label al mínimo de los tres.

El uso de minFontSize quedó en desuso en UILabel en iOS 6 y en las NSString dibujo de NSString en iOS 7. Si desea usarlo y encontrar el tamaño de fuente real utilizado, debe usar el método en desuso que mencionó en su pregunta.

El reemploop para minFontSize es minimumScaleFactor . Si desea encontrar el factor de escala real utilizado, debe crear un NSStringDrawingContext y pasarlo en el post boundingRectWithSize:options:attributes:context: así:

 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; 

Ampliando la respuesta de Ferran

Para expandir para llenar el ancho o la altura, lo que sea que toque primero

Versión 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; } 

Luego haga algo como esto para usarlo (diga que su label se llama 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 

Versión del 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; } 

Mi búsqueda específica ha sido el tamaño de la fuente en 2 tags por igual con ajustaFontSizeToFitWidth habilitado. La solución funciona en iOS 6 y 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]; } 

El código siguiente no es compatible con minFontSize y lineBreakMode, así que si los necesita, debería mejorarlo usted mismo:

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

Solución simple para UILabel de una línea:

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

El código de Erik van der Neut trabajó para mí, así que lo traduje en Swift y lo envolví en una extensión 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) } }