web-dev-qa-db-fra.com

Ajuster la hauteur de UILabel au texte

J'ai quelques étiquettes dont je veux ajuster la hauteur au texte, c'est le code que j'ai écrit pour ça maintenant

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
}

EDIT:

Le problème ne se trouvait pas dans ce morceau de code, ma solution est donc dans la question elle-même. Cela pourrait encore être utile pour les autres!

99
TheBurgerShot

Je viens de mettre cela dans un terrain de jeu et cela fonctionne pour moi.

Mise à jour pour Swift 4.

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

170
Anorak

Si vous utilisez AutoLayout , vous pouvez régler UILabel height en configurant l'interface utilisateur uniquement.

Pour iOS8 ou supérieur

  • Définir la contrainte avant/après pour votre UILabel
  • Et changez les lignes de UILabel de 1 à 0

enter image description here

Pour iOS7

  • Tout d'abord , vous devez ajouter une hauteur de conteneur pour UILabel
  • Puis , modifiez la relation de Equal à Greater than or Equal

enter image description here

  • Enfin , changez les lignes de UILabel de 1 à 0

enter image description here

Votre UILabel augmentera automatiquement la hauteur en fonction du texte

58
Phan Van Linh

Je crée cette extension si vous voulez

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

J'ai une solution de travail solide.

dans layoutSubviews:

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

dans le sélecteur de texte:

    _title.text = newValue
    setNeedsLayout()

PD. bien sûr avec ces paramètres UILabel:

    _title.lineBreakMode = .ByWordWrapping
    _title.numberOfLines = 0
7
dimpiax

Juste en mettant:

label.numberOfLines = 0

L'étiquette ajuste automatiquement sa hauteur en fonction de la quantité de texte entrée.

6
Jordan Amman

sur la base de la réponse d'Anorak, je partage également l'inquiétude de Zorayr. J'ai donc ajouté quelques lignes pour supprimer UILabel et renvoyer uniquement CGFloat. Je ne sais pas si cela aide, car le code d'origine n'ajoute pas UIabel, mais ne jette pas d'erreur, j'utilise donc le code ci-dessous:

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
}
5
LeftyT

Dans Swift 4.1 et Xcode 9.4.1

Seulement étapes

étape 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
}

étape 2)

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

étape 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)
4
iOS

La solution proposée par Anorak en tant que propriété calculée dans une extension pour 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
         }
    }
}

Usage:

self.brandModelLabel.frame.size.height = self.brandModelLabel.optimalHeight)
3
Philipp Otto

Après la réponse de @Anorak, j’ai ajouté cette extension à String et j’ai envoyé un encart en tant que paramètre, car vous aurez souvent besoin d’un remplissage pour votre texte. Quoi qu'il en soit, vous trouverez peut-être cela utile.

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
    }
}
3
Lirik

Voici comment calculer la hauteur du texte dans Swift. Vous pouvez ensuite obtenir la hauteur à partir du rect et définir la hauteur de contrainte de l'étiquette ou de 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)
2
Collin

Swift 4.0

self.messageLabel = UILabel (cadre: CGRect (x: 70, y: 60, largeur: UIScreen.main.bounds.width - 80, hauteur: 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, s’applique à des paragraphes entiers et non à des mots entre paragraphes. Cette propriété est définie par défaut surTruncatingTail.

Ce lien décrit la manière de faire de même

2
7ur7l3

il suffit d'appeler cette méthode lorsque vous avez besoin d'une hauteur dynamique pour le libellé.

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
}
1
Shubham bairagi

La méthode d'extension Swift 4.1 pour calculer la hauteur de l'étiquette:

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
    }

}
1
user7718859

Swift 4.

Au lieu de calculer la hauteur du texte/de l’étiquette, je redimensionne simplement l’étiquette après avoir inséré le texte (dynamique).

En supposant que myLabel soit le UILabel en question:

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

Et voici la partie amusante:

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

Pour rendre les étiquettes dynamiques dans Swift, ne donnez pas de hauteur à constarint et dans le storyboard, indiquez un nombre de lignes égal à 0, ainsi que la contrainte de fond. C'est la meilleure façon de gérer les étiquettes dynamiques en fonction de la taille de leur contenu.

0
Ranjeet Raushan