110 votes

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

100voto

Glenn Howes Points 747

Depuis sizeWithFont est déprécié, je vais simplement mettre à jour ma réponse originale pour utiliser Swift 4 et .size

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

import UIKit

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

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

81voto

wcochran Points 1150

sizeWithFont: est désormais obsolète, utilisez sizeWithAttributes: à la place :

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

76voto

Daniel Rinser Points 5755

C'est exactement ce que vous pouvez faire par l'intermédiaire des différents sizeWithFont: méthodes en Ajouts à NSString UIKit . Dans votre cas, la variante la plus simple devrait suffire (puisque vous n'avez pas d'étiquettes à plusieurs lignes) :

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

Il existe plusieurs variantes de cette méthode, par exemple, certaines tiennent compte des modes de coupure de ligne ou des tailles maximales.

72voto

Adrian Points 7651

Mise à jour septembre 2019

Cette réponse est une façon beaucoup plus propre de le faire en utilisant une nouvelle syntaxe.

Réponse originale

Sur la base de L'excellente réponse de Glenn Howes J'ai créé une extension pour calculer la largeur d'une chaîne de caractères. Si vous faites quelque chose comme définir la largeur d'une chaîne de caractères, vous pouvez l'utiliser pour calculer la largeur d'une chaîne de caractères. UISegmentedControl ce qui permet de 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)
    }
}

l'usage :

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

52voto

eonist Points 1748

Oneliner dans Swift 4.2

let size = "abc".size(withAttributes:[.font: UIFont.systemFont(ofSize: 18.0)])

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X