Calcule el tamaño de UILabel basado en String en Swift

Estoy tratando de calcular la altura de un UILabel basado en diferentes longitudes de cadena.

func calculateContentHeight() -> CGFloat{ var maxLabelSize: CGSize = CGSizeMake(frame.size.width - 48, CGFloat(9999)) var contentNSString = contentText as NSString var expectedLabelSize = contentNSString.boundingRectWithSize(maxLabelSize, options: NSStringDrawingOptions.UsesLineFragmentOrigin, attributes: [NSFontAttributeName: UIFont.systemFontOfSize(16.0)], context: nil) print("\(expectedLabelSize)") return expectedLabelSize.size.height } 

Arriba está la función actual que uso para determinar la altura pero no está funcionando. Agradecería enormemente cualquier ayuda que pueda obtener. Preferiría la respuesta en Swift y no en Objective C.

Use una extensión en String

Swift 3

 extension String { func height(withConstrainedWidth width: CGFloat, font: UIFont) -> CGFloat { let constraintRect = CGSize(width: width, height: .greatestFiniteMagnitude) let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [NSFontAttributeName: font], context: nil) return ceil(boundingBox.height) } func width(withConstrainedHeight height: CGFloat, font: UIFont) -> CGFloat { let constraintRect = CGSize(width: .greatestFiniteMagnitude, height: height) let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [NSFontAttributeName: font], context: nil) return ceil(boundingBox.width) } } 

y también en NSAttributedString (que a veces es muy útil)

 extension NSAttributedString { func height(withConstrainedWidth width: CGFloat) -> CGFloat { let constraintRect = CGSize(width: width, height: .greatestFiniteMagnitude) let boundingBox = boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, context: nil) return ceil(boundingBox.height) } func width(withConstrainedHeight height: CGFloat) -> CGFloat { let constraintRect = CGSize(width: .greatestFiniteMagnitude, height: height) let boundingBox = boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, context: nil) return ceil(boundingBox.width) } } 

Swift 4

Simplemente cambie el valor de los attributes en la extension String Métodos de extension String

de

 [NSFontAttributeName: font] 

a

 [.font : font] 

Para texto de líneas múltiples, esta respuesta no funciona correctamente. Puedes construir una extensión de cadena diferente usando UILabel

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

UILabel obtiene un ancho fijo y .numberOfLines se establece en 0. Al agregar el texto y al llamar a .sizeToFit (), se ajusta automáticamente a la altura correcta.

El código está escrito en Swift 3 🔶🐦

 extension String{ func widthWithConstrainedHeight(_ height: CGFloat, font: UIFont) -> CGFloat { let constraintRect = CGSize(width: CGFloat.greatestFiniteMagnitude, height: height) let boundingBox = self.boundingRect(with: constraintRect, options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: [NSFontAttributeName: font], context: nil) return ceil(boundingBox.width) } func heightWithConstrainedWidth(_ width: CGFloat, font: UIFont) -> CGFloat? { let constraintRect = CGSize(width: width, height: CGFloat.greatestFiniteMagnitude) let boundingBox = self.boundingRect(with: constraintRect, options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: [NSFontAttributeName: font], context: nil) return ceil(boundingBox.height) } } 

Esta es mi respuesta en Swift 4.1 y Xcode 9.4.1

 //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) //Function to calculate height for label based on text 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 } 

Ahora llama a esta función

 //Call this function let height = heightForView(text: "This is your text", font: UIFont.systemFont(ofSize: 17), width: 300) print(height)//Output : 41.0 
 @IBOutlet weak var constraintTxtV: NSLayoutConstraint! func TextViewDynamicallyIncreaseSize() { let contentSize = self.txtVDetails.sizeThatFits(self.txtVDetails.bounds.size) let higntcons = contentSize.height constraintTxtV.constant = higntcons }