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

Mostré el texto en UILabel usando el método de ajuste. Ahora quiero encontrar la cantidad de líneas que hay en UILabel.

Si hay alguna forma de encontrar el número de líneas de UILabel, cuente.

Gracias.

Como se señaló, esta publicación se refiere a cómo obtener la altura, en lugar de la cantidad de líneas. Para obtener el número de líneas,

  1. Obtenga la altura para una sola letra, por ejemplo, @"A" .
  2. Divida la altura de la cuerda por la altura obtenida en 1 arriba.

P.ej

 CGFloat unitHeight = [@"A" heightForWidth:width usingFont:font]; CGFloat blockHeight = [text heightForWidth:width usingFont:font]; NSInteger numberOfLines = ceilf(blockHeight / unitHeight); // need to #include  for ^^^^^ 

A partir de iOS 7, se modificó la forma de obtener la altura deseada de una etiqueta. Para obtener la altura, puede usar el siguiente código:

 NSStringDrawingContext *context = [[NSStringDrawingContext alloc] init]; CGSize labelSize = (CGSize){width, FLT_MAX}; CGRect r = [self boundingRectWithSize:labelSize options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName: font} context:context]; 

donde la altura es r.size.height . Tenga en cuenta que la font debe ser proporcionada. Puede poner esto en una categoría para NSString por conveniencia, por ej.

 @implementation NSString (HeightCalc) - (CGFloat)heightForWidth:(CGFloat)width usingFont:(UIFont *)font { NSStringDrawingContext *context = [[NSStringDrawingContext alloc] init]; CGSize labelSize = (CGSize){width, FLT_MAX}; CGRect r = [self boundingRectWithSize:labelSize options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName: font} context:context]; return r.size.height; } @end 

(Haga la gestión de la memoria si no usa ARC, por cierto).

Para iOS 6 y abajo:

Supongamos que tiene UILabel *myLabel y desea conocer la altura de la etiqueta (con algunos ajustes, puede obtener el n. ° de líneas dividiendo la altura con un número apropiado que depende del tamaño de la fuente).

 UILabel *myLabel; CGSize labelSize = [myLabel.text sizeWithFont:myLabel.font constrainedToSize:myLabel.frame.size lineBreakMode:UILineBreakModeWordWrap]; CGFloat labelHeight = labelSize.height; 

Espero que ayude. Si no funciona, házmelo saber y profundizaré más. Además, código no probado, pero funcionó a partir de la referencia.

Para un ejemplo más completo, aquí está el código que puse en el método viewDidLoad: de un controlador de vista:

 [super viewDidLoad]; UILabel *myLabel = [[UILabel alloc] initWithFrame:CGRectMake(50,50,200,350)]; myLabel.numberOfLines = 0; myLabel.lineBreakMode = UILineBreakModeWordWrap; myLabel.text = @"This is some text in a UILabel which is long enough to wrap around the lines in said UILabel. This is a test, this is only a test."; [self.view addSubview:myLabel]; CGSize labelSize = [myLabel.text sizeWithFont:myLabel.font constrainedToSize:myLabel.frame.size lineBreakMode:UILineBreakModeWordWrap]; CGFloat labelHeight = labelSize.height; NSLog(@"labelHeight = %f", labelHeight); [myLabel release]; 

La salida de NSLog va:

 2010-11-15 18:25:27.817 so_labelheight[728:307] labelHeight = 126.000000 

Para iOS7 y superior, la forma oficialmente aprobada de contar el número de líneas es usar TextKit:

 func numberOfLinesForString(string: String, size: CGSize, font: UIFont) -> Int { let textStorage = NSTextStorage(string: string, attributes: [NSFontAttributeName: font]) let textContainer = NSTextContainer(size: size) textContainer.lineBreakMode = .ByWordWrapping textContainer.maximumNumberOfLines = 0 textContainer.lineFragmentPadding = 0 let layoutManager = NSLayoutManager() layoutManager.textStorage = textStorage layoutManager.addTextContainer(textContainer) var numberOfLines = 0 var index = 0 var lineRange : NSRange = NSMakeRange(0, 0) for (; index < layoutManager.numberOfGlyphs; numberOfLines++) { layoutManager.lineFragmentRectForGlyphAtIndex(index, effectiveRange: &lineRange) index = NSMaxRange(lineRange) } return numberOfLines } 

El método -sizeWithFont:constrainedToSize:lineBreakMode ahora está en desuso. -boundingRectWithSize:options:attributes:context: utilizar el método -boundingRectWithSize:options:attributes:context: now.

Aquí hay un ejemplo:

 CGSize boundingRectSize = CGSizeMake(widthToConstrainTo, CGFLOAT_MAX); NSDictionary *attributes = @{NSFontAttributeName : [UIFont fontWithName:fontName size:14]}; CGRect labelSize = [labelString boundingRectWithSize:boundingRectSize options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:attributes context:nil]; 

En el ejemplo anterior, sé el ancho al que quiero restringir la etiqueta, pero como no estoy seguro de la altura, CGFLOAT_MAX altura usando CGFLOAT_MAX . Para las options , necesita usar NSStringDrawingUsesLineFragmentOrigin y NSStringDrawingUsesFontLeading si está intentando calcular el tamaño de una etiqueta que puede ser cualquier cantidad de líneas.

sizeWithFont está en desuso en iOS 7, puede usar esto en su lugar:

 - (int)lineCountForText:(NSString *) text { UIFont *font = ... CGRect rect = [text boundingRectWithSize:CGSizeMake(200, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : font} context:nil]; return ceil(rect.size.height / font.lineHeight); } 

Si está buscando esta respuesta en Swift 2 + / iOS 8, se vería así:

 func numberOfLinesInLabel(yourString: String, labelWidth: CGFloat, labelHeight: CGFloat, font: UIFont) -> Int { let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.minimumLineHeight = labelHeight paragraphStyle.maximumLineHeight = labelHeight paragraphStyle.lineBreakMode = .ByWordWrapping let attributes: [String: AnyObject] = [NSFontAttributeName: font, NSParagraphStyleAttributeName: paragraphStyle] let constrain = CGSizeMake(labelWidth, CGFloat(Float.infinity)) let size = yourString.sizeWithAttributes(attributes) let stringWidth = size.width let numberOfLines = ceil(Double(stringWidth/constrain.width)) return Int(numberOfLines) } 

(Originalmente publiqué mi respuesta aquí, pero no tengo la reputación suficiente para comentar o marcar duplicados).

Las otras respuestas que he encontrado 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)
 func getHeight(text: NSString, width:CGFloat, font: UIFont) -> CGFloat { let rect = text.boundingRect(with: CGSize.init(width: width, height: CGFloat.greatestFiniteMagnitude), options: ([NSStringDrawingOptions.usesLineFragmentOrigin,NSStringDrawingOptions.usesFontLeading]), attributes: [NSFontAttributeName:font], context: nil) return rect.size.height } 

texto: la etiqueta cuya altura necesita encontrar con la cadena dada

ancho: el ancho de UILabel

fuente: fuente de UILabel