iOS 7 sizeWithAttributes: remplacement de sizeWithFont: constrainedToSize


132

Comment renvoyer un CGSize texte multiligne à partir de la nouvelle méthode iOS 7 sizeWithAttributes?

Je voudrais que cela produise les mêmes résultats que sizeWithFont: constrainedToSize.

NSString *text = @"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus eu urna quis lacus imperdiet scelerisque a nec neque. Mauris eget feugiat augue, vitae porttitor mi. Curabitur vitae sollicitudin augue. Donec id sapien eros. Proin consequat tellus in vehicula sagittis. Morbi sed felis a nibh hendrerit hendrerit. Lorem ipsum dolor sit."

CGSize textSize = [text sizeWithAttributes:@{ NSFontAttributeName : [UIFont fontWithName:@"HelveticaNeue-Light" size:16.0] }];

Cette méthode ne produit que la hauteur d'une seule ligne de texte.



6
+1 pour avoir la même police que moi :)
Lescai Ionel

Réponses:


293

Eh bien, vous pouvez essayer ceci:

NSDictionary *attributes = @{NSFontAttributeName: [UIFont fontWithName:@"HelveticaNeue" size:14]};
// NSString class method: boundingRectWithSize:options:attributes:context is
// available only on ios7.0 sdk.
CGRect rect = [textToMeasure boundingRectWithSize:CGSizeMake(width, CGFLOAT_MAX)
                                          options:NSStringDrawingUsesLineFragmentOrigin
                                       attributes:attributes
                                          context:nil];

4
Pour la première fois, je vois cette notation pour les dictionnaires @{...}. Comment appelle-t-on ceci?
Martin Berger

4
Frère, je perdais presque confiance en SO, puis je suis venu ici.
NSPunk

21
Sensationnel. Tellement plus obtus que la sizeWithFont:constrainedToSize:méthode originale qui était obsolète. Apple doit vraiment nous détester. Dans tous les cas, +1.
aroth

1
Pourquoi utilisez-vous à la MAXFLOATplace de CGFLOAT_MAX?
Julian F. Weinert

19
Version Swift:var size = textToMeasure.boundingRectWithSize( CGSizeMake(width, CGFloat.max), options: NSStringDrawingOptions.UsesLineFragmentOrigin, attributes:attrs, context:nil).size
mdziadkowiec

23

Voici comment je l'ai fait:

    // Get a font to draw it in
UIFont *font = [UIFont boldSystemFontOfSize: 28];

CGRect textRect;
NSDictionary *attributes = @{NSFontAttributeName: font};

// How big is this string when drawn in this font?
textRect.size = [text sizeWithAttributes:attributes];

// Draw the string
[text drawInRect:textRect withAttributes:attributes];

2
Cela ne fonctionnera pas si une longue chaîne se rompt en fin de ligne. Reportez-vous à la réponse d'elio.d, qui est correcte.
Julian F. Weinert

4

Swift 2.3:

let attributes = [NSFontAttributeName:UIFont(name: "HelveticaNeue", size: 14)]
let rect = NSString(string: textToMeasure).boundingRectWithSize(
        CGSizeMake(width, CGFLOAT_MAX), 
        options: NSStringDrawingOptions.UsesLineFragmentOrigin, 
        attributes: attributes, context: nil)

Swift 4:

let attributes = [NSFontAttributeName:UIFont(name: "HelveticaNeue", size: 14)]
let rect = NSString(string: textToMeasure).boundingRect(
                    with: CGSize(width: width, height: CGFloat.greatestFiniteMagnitude),
                    options: NSStringDrawingOptions.usesLineFragmentOrigin,
                    attributes: attributes as [NSAttributedString.Key : Any], context: nil)

3

Voici ma méthode pour traiter les deux situations, va dans une NSStringcatégorie.

- (CGSize) sizeWithFontOrAttributes:(UIFont *) font {
    if (IS_IOS7) {
        NSDictionary *fontWithAttributes = @{NSFontAttributeName:font};
        return [self sizeWithAttributes:fontWithAttributes];
    } else {
        return [self sizeWithFont:font];
    }
}

3

Pour Xamarin.iOS:

UIFont descriptionLabelFont =  UIFont.SystemFontOfSize (11);
NSString textToMeasure = (NSString)DescriptionLabel.Text;

CGRect labelRect = textToMeasure.GetBoundingRect (
    new CGSize(this.Frame.Width, nfloat.MaxValue), 
    NSStringDrawingOptions.UsesLineFragmentOrigin, 
    new UIStringAttributes () { Font = descriptionLabelFont }, 
    new NSStringDrawingContext ()
);

2

Si vous avez le texte, la police, numberOfLines et la largeur de votre jeu d'étiquettes, cette méthode renvoie la taille de votre étiquette:

myLabel.numberOfLines = 0;

CGSize size = [myLabel sizeThatFits:CGSizeMake(myLabel.frame.size.width, CGFLOAT_MAX)];`

1

Comme alternative, si vous regardez UITextView, vous pouvez toujours utiliser la NSLayoutManagerméthode:

CGSize textSize = [textView.layoutManager usedRectForTextContainer:textView.textContainer].size;

Vous pouvez également trouver la hauteur de ligne pour une police donnée par:

UIFont *font;
CGFloat lineHeight = font.lineHeight;

0

[En tant que nouvel utilisateur, je ne peux pas publier de commentaire sur la réponse de @ testing, mais pour rendre sa réponse (pour xamarin.ios) plus utile]

Nous pouvons renvoyer un CGRect et n'utiliser que le paramètre de hauteur pour l'élément d'interface graphique que nous ciblons UIButton etc. en passant tous les paramètres dont nous avons besoin comme ci-dessous

    public CGRect GetRectForString(String strMeasure, int fontSize, nfloat guiItemWidth)
    {
        UIFont descriptionLabelFont =  UIFont.SystemFontOfSize (fontSize);
        NSString textToMeasure = (NSString)strMeasure;

        CGRect labelRect = textToMeasure.GetBoundingRect (
            new CGSize(guiItemWidth, nfloat.MaxValue), 
            NSStringDrawingOptions.UsesLineFragmentOrigin, 
            new UIStringAttributes () { Font = descriptionLabelFont }, 
            new NSStringDrawingContext ()
        );

        return labelRect;
    }

        header_Revision.Frame = new CGRect (5
                                            , verticalAdjust
                                            , View.Frame.Width-10
                                            , GetRectForString( header_Revision.Title(UIControlState.Normal)
                                                              , 18
                                                              , View.Frame.Width-10 ).Height
                                            );

C'était en fait censé être sous le bon code de test pour Xamarin.IOS :) J'espère que cela aidera tout le monde :)
Matt

Lorsque vous avez plus de représentants, un commentaire comme celui-ci est généralement ajouté à la publication. Vous ne pouvez pas encore faire cela, alors merci pour les données supplémentaires et bienvenue dans Stack Overflow.
Stuart Siegler

0
CGSize stringsize = [lbl.text sizeWithAttributes:
                         @{NSFontAttributeName:[UIFont fontWithName:FontProximaNovaRegular size:12.0]}];


CGSize adjustedSize = CGSizeMake(ceilf(stringsize.width), ceilf(stringsize.height));

utiliser la ceilfméthode pour gérer correctement

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.