¿Cómo encontrar el número real de líneas de UILabel?

¿Cómo puedo encontrar el número real de líneas de un UILabel después de haberlo inicializado con un text y una font ? Establecí su propiedad numberOfLines en 0 , por lo que se expandirá a cuantas líneas sean necesarias. Pero entonces, ¿cómo puedo saber cuántas líneas obtuvo finalmente después de configurar su text ?

Encontré preguntas similares, pero ninguna parece brindar una respuesta concisa y me parece que debe ser realmente fácil obtenerla sin ningún tipo de sobrecarga al hacer malabares con el boundingRectWithSize o sizeWithFont , …

Primero establece el texto en UILabel

Primera opción :

Primero, calcule la altura del texto de acuerdo con la fuente:

 NSInteger lineCount = 0; CGSize labelSize = (CGSize){yourLabel.frame.size.width, MAXFLOAT}; CGRect requiredSize = [self boundingRectWithSize:labelSize options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName: yourLabel.font} context:nil]; 

Ahora calcule el número de líneas:

 int charSize = lroundf(yourLabel.font.lineHeight); int rHeight = lroundf(requiredSize.height); lineCount = rHeight/charSize; NSLog(@"No of lines: %i",lineCount); 

Segunda opción :

  NSInteger lineCount = 0; CGSize textSize = CGSizeMake(yourLabel.frame.size.width, MAXFLOAT); int rHeight = lroundf([yourLabel sizeThatFits:textSize].height); int charSize = lroundf(yourLabel.font.lineHeight); lineCount = rHeight/charSize; NSLog(@"No of lines: %i",lineCount); 

Swift 3 (IOS 10.3)

 extension UILabel { var numberOfVisibleLines: Int { let textSize = CGSize(width: CGFloat(self.frame.size.width), height: CGFloat(MAXFLOAT)) let rHeight: Int = lroundf(Float(self.sizeThatFits(textSize).height)) let charSize: Int = lroundf(Float(self.font.pointSize)) return rHeight / charSize } } 

Uso

 print(yourLabel.numberOfVisibleLines) 

Aquí hay una versión rápida de la solución @Paresh:

 func lines(label: UILabel) -> Int { let textSize = CGSize(width: label.frame.size.width, height: CGFloat(Float.infinity)) let rHeight = lroundf(Float(label.sizeThatFits(textSize).height)) let charSize = lroundf(Float(label.font.lineHeight)) let lineCount = rHeight/charSize return lineCount } 

EDITAR: No sé por qué, pero el código devuelve 2 líneas más que el número real de líneas, para mi solución, las restaba antes de devolver lineCount.

Ninguno de estos funcionó para mí. Debajo uno hizo,

Swift 4:

 extension UILabel { func calculateMaxLines() -> Int { let maxSize = CGSize(width: frame.size.width, height: CGFloat(Float.infinity)) let charSize = font.lineHeight let text = (self.text ?? "") as NSString let textSize = text.boundingRect(with: maxSize, options: .usesLineFragmentOrigin, attributes: [.font: font], context: nil) let lines = Int(textSize.height/charSize) return lines } } 

Swift 3:

 extension UILabel { func calculateMaxLines() -> Int { let maxSize = CGSize(width: frame.size.width, height: CGFloat(Float.infinity)) let charSize = font.lineHeight let text = (self.text ?? "") as NSString let textSize = text.boundingRect(with: maxSize, options: .usesLineFragmentOrigin, attributes: [NSFontAttributeName: font], context: nil) let lines = Int(textSize.height/charSize) return lines } } 

Las otras respuestas aquí no respetan la propiedad numberOfLines de UILabel cuando está configurada en algo distinto de 0.

Aquí hay otra opción que puede agregar a su categoría o subclase:

 - (NSUInteger)lineCount { CGSize size = [self sizeThatFits:CGSizeMake(self.frame.size.width, CGFLOAT_MAX)]; return MAX((int)(size.height / self.font.lineHeight), 0); } 

Algunas notas:

  • Estoy usando esto en un UILabel con texto atribuido, sin establecer realmente la propiedad de la font , y está funcionando bien. Obviamente, se encontraría con problemas si estuviera usando varias fonts en su attributedText .
  • Si está subclasificando UILabel para tener inserciones de borde personalizadas (por ejemplo anulando drawTextInRect: que es un truco drawTextInRect: que encontré aquí ), entonces debe recordar tomar en cuenta esas inserciones cuando calcule el size anterior. Por ejemplo: CGSizeMake(self.frame.size.width - (self.insets.left + self.insets.right), CGFLOAT_MAX)

Aquí está el Código Swift3 aquí puede definir el valor Int y obtener el alto del tamaño del texto usando (MAXFLOAT) y usando esa altura puede obtener la altura total de UILabel y al proporcionar esa altura total por tamaño de carácter puede obtener la línea real recuento de UILabel.

 var lineCount: Int = 0 var textSize = CGSize(width: CGFloat(yourLabel.frame.size.width), height: CGFloat(MAXFLOAT)) var rHeight: Int = lroundf(yourLabel.sizeThatFits(textSize).height) var charSize: Int = lroundf(yourLabel.font.leading) lineCount = rHeight / charSize print("No of lines: \(lineCount)") 

Siguiendo la respuesta de @ Prince, ahora implementé una categoría en UILabel siguiente manera (nótese que corregí algunos errores de syntax menores en su respuesta que no permitían la comstackción del código):

UILabel + Util.h

 #import  @interface UILabel (Util) - (NSInteger)lineCount; @end 

UILabel + Util.,

 #import "UILabel+Util.h" @implementation UILabel (Util) - (NSInteger)lineCount { // Calculate height text according to font NSInteger lineCount = 0; CGSize labelSize = (CGSize){self.frame.size.width, FLT_MAX}; CGRect requiredSize = [self.text boundingRectWithSize:labelSize options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName: self.font} context:nil]; // Calculate number of lines int charSize = self.font.leading; int rHeight = requiredSize.size.height; lineCount = rHeight/charSize; return lineCount; } @end 

Puede encontrar el número total de líneas disponibles en su etiqueta personalizada. Compruebe este código …

 NSInteger numberOfLines = [self lineCountForText:@"YOUR TEXT"]; - (int)lineCountForText:(NSString *) text { UIFont *font = [UIFont systemFontOfSize: 15.0]; int width=Your_LabelWidht; CGRect rect = [text boundingRectWithSize:CGSizeMake(width, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : font} context:nil]; return ceil(rect.size.height / font.lineHeight); } 

Xamarin.iOS

Gracias a las respuestas que todos brindaron anteriormente.

Esto obtiene el número de líneas visibles.

 public static int VisibleLineCount(this UILabel label) { var textSize = new CGSize(label.Frame.Size.Width, nfloat.MaxValue); nfloat rHeight = label.SizeThatFits(textSize).Height; nfloat charSize = label.Font.LineHeight; return Convert.ToInt32(rHeight / charSize); } 

Esto obtiene el número real de líneas que el texto ocupará en la pantalla.

 public static int LineCount(this UILabel label) { var maxSize = new CGSize(label.Frame.Size.Width, nfloat.MaxValue); var charSize = label.Font.LineHeight; var text = (label.Text ?? "").ToNSString(); var textSize = text.GetBoundingRect(maxSize, NSStringDrawingOptions.UsesLineFragmentOrigin, new UIStringAttributes() { Font = label.Font }, null); return Convert.ToInt32(textSize.Height / charSize); } 

Un método de ayuda que considero útil para mi caso de uso.

 public static bool IsTextTruncated(this UILabel label) { if (label.Lines == 0) { return false; } return (label.LineCount() > label.Lines); } 

Para obtener un recuento de líneas más preciso:

  • Use font.lineHeight lugar de font.pointSize
  • round () el recuento de líneas después de la división

Xamarin iOS

 label.Text = text; var lineCount = 0; var textSize = new CGSize(label.Frame.Size.Width, float.MaxValue); var height = label.SizeThatFits(textSize).Height; var fontHeight = label.Font.LineHeight; lineCount = Convert.ToInt32(height / fontHeight);