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

Resuelto Cody Weaver asked hace 54 años • 14 respuestas

Estoy intentando calcular la altura de UILabel en función de 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 funciona. Agradecería mucho cualquier ayuda que pueda obtener. Preferiría la respuesta en Swift y no en Objective C.

Cody Weaver avatar Jan 01 '70 08:01 Cody Weaver
Aceptado

Utilice una extensión enString

veloz 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(lo cual es muy útil a veces)

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

Rápido 4 y 5

Simplemente cambie el valor de attributesen los extension Stringmétodos.

de

[NSFontAttributeName: font]

a

[.font : font]
Kaan Dedeoglu avatar May 26 '2015 05:05 Kaan Dedeoglu

Aquí hay una solución simple que funciona para mí... similar a algunas de las otras publicadas, pero no necesita lasizeToFit

Tenga en cuenta que esto está escrito en Swift 5

let lbl = UILabel()
lbl.numberOfLines = 0
lbl.font = UIFont.systemFont(ofSize: 12) // make sure you set this correctly 
lbl.text = "My text that may or may not wrap lines..."

let width = 100.0 // the width of the view you are constraint to, keep in mind any applied margins here
 
let height = lbl.systemLayoutSizeFitting(CGSize(width: width, height: UIView.layoutFittingCompressedSize.height), withHorizontalFittingPriority: .required, verticalFittingPriority: .fittingSizeLevel).height

Esto maneja el ajuste de línea y demás. No es el código más elegante, pero hace el trabajo.

RyanG avatar Jul 01 '2019 19:07 RyanG