web-dev-qa-db-fra.com

Comment calculer la largeur d'une chaîne de texte d'une police et d'une taille de police spécifiques?

J'ai un UILabel qui affiche des caractères. Comme "x", "y" ou "rpm". Comment puis-je calculer la largeur du texte dans l'étiquette (cela n'utilise pas tout l'espace disponible)? Ceci est pour la mise en page automatique, où une autre vue aura un rectangle de cadre plus grand si UILabel a un texte plus petit à l'intérieur. Existe-t-il des méthodes pour calculer cette largeur de texte lorsqu'une taille UIFont et une police sont spécifiées? Il n'y a pas non plus de saut de ligne et une seule ligne.

54
HelloMoon

Vous pouvez faire exactement cela via les différentes méthodes sizeWithFont: dans NSString UIKit Additions . Dans votre cas, la variante la plus simple devrait suffire (puisque vous n'avez pas d'étiquettes multilignes):

NSString *someString = @"Hello World";
UIFont *yourFont = // [UIFont ...]
CGSize stringBoundingBox = [someString sizeWithFont:yourFont];

Il existe plusieurs variantes de cette méthode, par exemple. certains considèrent les modes de saut de ligne ou les tailles maximales.

63
Daniel Rinser

sizeWithFont: est maintenant obsolète, utilisez plutôt sizeWithAttributes::

UIFont *font = [UIFont fontWithName:@"Helvetica" size:30];
NSDictionary *userAttributes = @{NSFontAttributeName: font,
                                 NSForegroundColorAttributeName: [UIColor blackColor]};
NSString *text = @"hello";
...
const CGSize textSize = [text sizeWithAttributes: userAttributes];
66
wcochran

Puisque sizeWithFont est obsolète, je vais simplement mettre à jour ma réponse originale en utilisant Swift 4 et .size

//: Playground - noun: a place where people can play

import UIKit

if let font = UIFont(name: "Helvetica", size: 24) {
   let fontAttributes = [NSAttributedStringKey.font: font]
   let myText = "Your Text Here"
   let size = (myText as NSString).size(withAttributes: fontAttributes)
}

La taille doit être la taille à l'écran de "Votre texte ici" en points. 

59
Glenn Howes

Sur la base de l'excellente réponse de Glenn Howes , j'ai créé une extension pour calculer la largeur d'une chaîne. Si vous faites quelque chose comme définir la largeur d'une UISegmentedControl, cela peut définir la largeur en fonction de la chaîne de titre du segment.

extension String {

    func widthOfString(usingFont font: UIFont) -> CGFloat {
        let fontAttributes = [NSAttributedString.Key.font: font]
        let size = self.size(withAttributes: fontAttributes)
        return size.width
    }

    func heightOfString(usingFont font: UIFont) -> CGFloat {
        let fontAttributes = [NSAttributedString.Key.font: font]
        let size = self.size(withAttributes: fontAttributes)
        return size.height
    }

    func sizeOfString(usingFont font: UIFont) -> CGSize {
        let fontAttributes = [NSAttributedString.Key.font: font]
        return self.size(withAttributes: fontAttributes)
    }
}

usage:

    // Set width of segmentedControl
    let starString = "⭐️"
    let starWidth = starString.widthOfString(usingFont: UIFont.systemFont(ofSize: 14)) + 16
    segmentedController.setWidth(starWidth, forSegmentAt: 3)
31
Adrian

Oneliner dans Swift 4.2 ????

let size = text.size(withAttributes:[.font: UIFont.systemFont(ofSize:18.0)])
7
eonist

Cette simple extension dans Swift fonctionne bien.

extension String {
    func size(OfFont font: UIFont) -> CGSize {
        return (self as NSString).size(attributes: [NSFontAttributeName: font])
    }
}

Usage:

let string = "hello world!"
let font = UIFont.systemFont(ofSize: 12)
let width = string.size(OfFont: font).width // size: {w: 98.912 h: 14.32}
4
JsW

Swift 4

extension String {
    func SizeOf(_ font: UIFont) -> CGSize {
        return self.size(withAttributes: [NSAttributedStringKey.font: font])
    }
}
3
W.M

Utilisez intrinsicContentSize pour rechercher la hauteur et la largeur du texte. 

yourLabel.intrinsicContentSize.width

Cela fonctionnera même si vous avez un espacement personnalisé entre votre chaîne comme "T E X T"

2
Alok

Ceci est pour Swift 2.3 Version. Vous pouvez obtenir la largeur de la chaîne.

var sizeOfString = CGSize()
if let font = UIFont(name: "Helvetica", size: 14.0)
    {
        let finalDate = "Your Text Here"
        let fontAttributes = [NSFontAttributeName: font] // it says name, but a UIFont works
        sizeOfString = (finalDate as NSString).sizeWithAttributes(fontAttributes)
    }
2
Mandeep Singh

Pour Swift 3.0+

extension String {
    func SizeOf_String( font: UIFont) -> CGSize {
        let fontAttribute = [NSFontAttributeName: font]
        let size = self.size(attributes: fontAttribute)  // for Single Line
       return size;
   }
}

Utilisez-le comme ...

        let Str = "ABCDEF"
        let Font =  UIFont.systemFontOfSize(19.0)
        let SizeOfString = Str.SizeOfString(font: Font!)
1
Lakhdeep Singh

La façon dont je le fais mon code est de faire une extension de UIFont: (Ceci est Swift 4.1)

extension UIFont {


    public func textWidth(s: String) -> CGFloat
    {
        return s.size(withAttributes: [NSAttributedString.Key.font: self]).width
    }

} // extension UIFont
0
MarkAurelius