Ajuste la altura de UILabel al texto

Tengo algunas tags que quiero ajustar su altura al texto, este es el código que escribí para esto ahora

func heightForView(text:String, font:UIFont, width:CGFloat) -> CGFloat{ let label:UILabel = UILabel(frame: CGRectMake(0, 0, width, CGFloat.max)) label.numberOfLines = 0 label.lineBreakMode = NSLineBreakMode.ByWordWrapping label.font = font label.text = text label.sizeToFit() return label.frame.height } 

EDITAR:

El problema no estaba en este fragmento de código, por lo que mi solución está en la pregunta en sí. ¡Puede ser útil para otros!

Acabo de poner esto en un patio de recreo y funciona para mí.

Actualizado para Swift 4.0

 import UIKit func heightForView(text:String, font:UIFont, width:CGFloat) -> CGFloat{ let label:UILabel = UILabel(frame: CGRectMake(0, 0, width, CGFloat.greatestFiniteMagnitude)) label.numberOfLines = 0 label.lineBreakMode = NSLineBreakMode.byWordWrapping label.font = font label.text = text label.sizeToFit() return label.frame.height } let font = UIFont(name: "Helvetica", size: 20.0) var height = heightForView("This is just a load of text", font: font, width: 100.0) 

Swift 3:

 func heightForView(text:String, font:UIFont, width:CGFloat) -> CGFloat{ let label:UILabel = UILabel(frame: CGRect(x: 0, y: 0, width: width, height: CGFloat.greatestFiniteMagnitude)) label.numberOfLines = 0 label.lineBreakMode = NSLineBreakMode.byWordWrapping label.font = font label.text = text label.sizeToFit() return label.frame.height } 

enter image description here

Si está utilizando AutoLayout , puede ajustar la altura de UILabel solo mediante la interfaz de usuario de configuración.

Para iOS8 o superior

  • Establecer la restricción de UILabel / final para su UILabel
  • Y cambie las líneas de UILabel de 1 a 0

enter image description here

Para iOS7

  • En primer lugar , debe agregar contiene altura para UILabel
  • Luego , modifique la relación de Equal a Greater than or Equal

enter image description here

  • Por último , cambie las líneas de UILabel de 1 a 0

enter image description here

Su UILabel boostá automáticamente la altura dependiendo del texto

Creo esta extensión si quieres

 extension UILabel { func setSizeFont (sizeFont: CGFloat) { self.font = UIFont(name: self.font.fontName, size: sizeFont)! self.sizeToFit() } } 

Simplemente estableciendo:

 label.numberOfLines = 0 

La etiqueta ajusta automáticamente su altura en función de la cantidad de texto ingresado.

Basándome en la respuesta de Anorak, también estoy de acuerdo con la preocupación de Zorayr, así que agregué un par de líneas para eliminar el UILabel y devolver solo el CGFloat, no sé si ayuda ya que el código original no agrega el UIabel, pero no arroja un error, entonces estoy usando el siguiente código:

 func heightForView(text:String, font:UIFont, width:CGFloat) -> CGFloat{ var currHeight:CGFloat! let label:UILabel = UILabel(frame: CGRectMake(0, 0, width, CGFloat.max)) label.numberOfLines = 0 label.lineBreakMode = NSLineBreakMode.ByWordWrapping label.font = font label.text = text label.sizeToFit() currHeight = label.frame.height label.removeFromSuperview() return currHeight } 

Tengo una solución de trabajo sólida.

en layoutSubviews:

  _title.frame = CGRect(x: 0, y: 0, width: bounds.width, height: 0) _title.sizeToFit() _title.frame.size = _title.bounds.size 

en el texto setter:

  _title.text = newValue setNeedsLayout() 

UPD. por supuesto con esta configuración de UILabel:

  _title.lineBreakMode = .ByWordWrapping _title.numberOfLines = 0 

La solución sugerida por Anorak como una propiedad calculada en una extensión para UILabel:

 extension UILabel { var optimalHeight : CGFloat { get { let label = UILabel(frame: CGRectMake(0, 0, self.frame.width, CGFloat.max)) label.numberOfLines = 0 label.lineBreakMode = self.lineBreakMode label.font = self.font label.text = self.text label.sizeToFit() return label.frame.height } } } 

Uso:

 self.brandModelLabel.frame.size.height = self.brandModelLabel.optimalHeight) 

Siguiendo la respuesta de @Anorak, agregué esta extensión a String y envié un recuadro como parámetro, porque muchas veces necesitará un relleno para su texto. De todos modos, tal vez algunos encuentren esto útil.

 extension String { func heightForWithFont(font: UIFont, width: CGFloat, insets: UIEdgeInsets) -> CGFloat { let label:UILabel = UILabel(frame: CGRectMake(0, 0, width + insets.left + insets.right, CGFloat.max)) label.numberOfLines = 0 label.lineBreakMode = NSLineBreakMode.ByWordWrapping label.font = font label.text = self label.sizeToFit() return label.frame.height + insets.top + insets.bottom } } 

Aquí es cómo calcular la altura del texto en Swift. A continuación, puede obtener la altura del rect y establecer la altura de la restricción de la etiqueta o textView, etc.

 let font = UIFont(name: "HelveticaNeue", size: 25)! let text = "This is some really long text just to test how it works for calculating heights in swift of string sizes. What if I add a couple lines of text?" let textString = text as NSString let textAttributes = [NSFontAttributeName: font] let textRect = textString.boundingRectWithSize(CGSizeMake(320, 2000), options: .UsesLineFragmentOrigin, attributes: textAttributes, context: nil) 

En veloz 4.1 y Xcode 9.4.1

Solo 3 pasos

Paso 1)

 //To calculate height for label based on text size and width func heightForView(text:String, font:UIFont, width:CGFloat) -> CGFloat { let label:UILabel = UILabel(frame: CGRect(x: 0, y: 0, width: width, height: CGFloat.greatestFiniteMagnitude)) label.numberOfLines = 0 label.lineBreakMode = NSLineBreakMode.byWordWrapping label.font = font label.text = text label.sizeToFit() return label.frame.height } 

Paso 2)

 //Call this function let height = heightForView(text: "This is your text", font: UIFont.systemFont(ofSize: 17), width: 300) print(height)//Output : 41.0 

Paso 3)

 //This is your label let proNameLbl = UILabel(frame: CGRect(x: 0, y: 20, width: 300, height: height)) proNameLbl.text = "This is your text" proNameLbl.font = UIFont.systemFont(ofSize: 17) proNameLbl.numberOfLines = 0 proNameLbl.lineBreakMode = .byWordWrapping infoView.addSubview(proNameLbl) 

simplemente llame a este método donde necesita altura dinámica para la etiqueta

 func getHeightforController(view: AnyObject) -> CGFloat { let tempView: UILabel = view as! UILabel var context: NSStringDrawingContext = NSStringDrawingContext() context.minimumScaleFactor = 0.8 var width: CGFloat = tempView.frame.size.width width = ((UIScreen.mainScreen().bounds.width)/320)*width let size: CGSize = tempView.text!.boundingRectWithSize(CGSizeMake(width, 2000), options:NSStringDrawingOptions.UsesLineFragmentOrigin, attributes: [NSFontAttributeName: tempView.font], context: context).size as CGSize return size.height } 

Swift 4.0

self.messageLabel = UILabel (frame: CGRect (x: 70, y: 60, width: UIScreen.main.boiners.width – 80, height: 30)

 messageLabel.text = message messageLabel.lineBreakMode = .byWordWrapping //in versions below swift 3 (messageLabel.lineBreakMode = NSLineBreakMode.ByWordWrapping) messageLabel.numberOfLines = 0 //To write any number of lines within a label scope messageLabel.textAlignment = .center messageLabel.textColor = UIColor.white messageLabel.font = messageLabel.font.withSize(12) messageLabel.sizeToFit() 

Blockquote NSParagraphStyle.LineBreakMode, se aplica a párrafos enteros, no a palabras dentro de los párrafos. Esta propiedad tiene vigencia tanto durante el dibujo normal como en los casos en que el tamaño de la fuente debe reducirse para ajustarse al texto de la etiqueta en su cuadro delimitador. Esta propiedad está configurada porTruncatingTail de manera predeterminada.

Este enlace describe la manera del guion gráfico de hacer lo mismo

Swift 4.0

En lugar de calcular la altura del texto / etiqueta, simplemente cambio el tamaño de la etiqueta después de insertar el texto (dynamic).

Suponiendo que myLabel es el UILabel en cuestión:

 let myLabel = UILabel(frame: CGRect(x: 0, y: 0, width: *somewidth*, height: *placeholder, eg 20*)) myLabel.numberOfLines = 0 myLabel.lineBreakMode = .byWordWrapping ... 

Y ahora viene la parte divertida:

 var myLabelText: String = "" { didSet { myLabel.text = myLabelText myLabel.sizeToFit() } } 

El método de extensión de Swift 4.1 para calcular la altura de la etiqueta:

 extension UILabel { func heightForLabel(text:String, font:UIFont, width:CGFloat) -> CGFloat { let label:UILabel = UILabel(frame: CGRect(x: 0, y: 0, width: width, height: CGFloat.greatestFiniteMagnitude)) label.numberOfLines = 0 label.lineBreakMode = NSLineBreakMode.byWordWrapping label.font = font label.text = text label.sizeToFit() return label.frame.height } }