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!
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
}
Si vous utilisez AutoLayout , vous pouvez régler UILabel
height en configurant l'interface utilisateur uniquement.
Pour iOS8 ou supérieur
UILabel
UILabel
de 1 à 0Pour iOS7
UILabel
Equal
à Greater than or Equal
UILabel
de 1 à 0Votre UILabel
augmentera automatiquement la hauteur en fonction du texte
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()
}
}
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
Juste en mettant:
label.numberOfLines = 0
L'étiquette ajuste automatiquement sa hauteur en fonction de la quantité de texte entrée.
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
}
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)
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)
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
}
}
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)
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.
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
}
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
}
}
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()
}
}
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.