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.

morcutt
la source
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];
huiléCode
la source
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];
Rongeur
la source
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)
Gelée
la source
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];
    }
}
Dan Rosenstark
la source
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 ()
);
essai
la source
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)];`
Marijn
la source
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;
Mikeho
la source
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
                                            );
Mat
la source
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

jenish
la source