Remplacement de -sizeWithFont obsolète: constrainedToSize: lineBreakMode: dans iOS 7?

146

Dans iOS 7, la méthode:

- (CGSize)sizeWithFont:(UIFont *)font
     constrainedToSize:(CGSize)size
         lineBreakMode:(NSLineBreakMode)lineBreakMode 

et la méthode:

- (CGSize)sizeWithFont:(UIFont *)font

sont obsolètes. Comment puis-je remplacer

CGSize size = [string sizeWithFont:font
                 constrainedToSize:constrainSize
                     lineBreakMode:NSLineBreakByWordWrapping];

et:

CGSize size = [string sizeWithFont:font];
user_Dennis_Mostajo
la source
2
la méthode de substitution est -sizeWithAttributes:.
holex
ok holex merci mais, comment puis-je utiliser une police de label comme un NSDIctionary? si mon code est comme: sizeWithFont: customlabel.font; le void demande "sizeWithAttributes: <# (NSDictionary *) #>"
user_Dennis_Mostajo
1
voici la documentation officielle de la façon dont vous pouvez définir les attributs: developer.apple.com/library/ios/documentation/UIKit/Reference/…
holex

Réponses:

219

Vous pouvez essayer ceci:

CGRect textRect = [text boundingRectWithSize:size
                                 options:NSStringDrawingUsesLineFragmentOrigin
                              attributes:@{NSFontAttributeName:FONT}
                                 context:nil];

CGSize size = textRect.size;

Changez simplement "FONT" pour une "[police UIFont ....]"

Xavier Maroñas
la source
13
Et où mentionnez-vous NSLineBreakByWordWrapping? Où est-ce passé?
user4951
32
NSLineBreakByWordWrappingirait dans un NSParagraphStyle. Ainsi par exemple: NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;Dans les attributs, vous devrez alors ajouter NSParagraphStyleAttributeName: paragraphStyle.copy...
Florian Friedrich
1
@ffried dans mon cas en ajoutant le paragraphStyle avec un saut de ligne autre que NSLineBreakByWordWrapping a entraîné le calcul de la taille pour une seule ligne… Des pensées?
manicaesar
9
N'oubliez pas que boundingRectWithSize:options:attributes:context:renvoie des valeurs fractionnaires. Vous devez faire ceil(textRect.size.height)et ceil(textRect.size.width)respectivement pour obtenir la hauteur / largeur réelle.
Florian Friedrich
20
Qu'est-ce que BOLIVIASize?
JRam13
36

Comme nous ne pouvons pas utiliser sizeWithAttributes pour tous les iOS supérieurs à 4.3, nous devons écrire du code conditionnel pour 7.0 et les versions antérieures d'iOS.

1) Solution 1:

if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) {
   CGSize size = CGSizeMake(230,9999);
   CGRect textRect = [specialityObj.name  
       boundingRectWithSize:size
                    options:NSStringDrawingUsesLineFragmentOrigin
                 attributes:@{NSFontAttributeName:[UIFont fontWithName:[AppHandlers zHandler].fontName size:14]}
                    context:nil];
   total_height = total_height + textRect.size.height;   
}
else {
   CGSize maximumLabelSize = CGSizeMake(230,9999); 
   expectedLabelSize = [specialityObj.name sizeWithFont:[UIFont fontWithName:[AppHandlers zHandler].fontName size:14] constrainedToSize:maximumLabelSize lineBreakMode:UILineBreakModeWordWrap]; //iOS 6 and previous. 
   total_height = total_height + expectedLabelSize.height;
}

2) Solution 2

UILabel *gettingSizeLabel = [[UILabel alloc] init];
gettingSizeLabel.font = [UIFont fontWithName:[AppHandlers zHandler].fontName size:16]; // Your Font-style whatever you want to use.
gettingSizeLabel.text = @"YOUR TEXT HERE";
gettingSizeLabel.numberOfLines = 0;
CGSize maximumLabelSize = CGSizeMake(310, 9999); // this width will be as per your requirement

CGSize expectedSize = [gettingSizeLabel sizeThatFits:maximumLabelSize];

La première solution est parfois de ne pas renvoyer la valeur appropriée de la hauteur. alors utilisez une autre solution. qui fonctionnera parfaitement.

La deuxième option est assez bien et fonctionne correctement dans tous les iOS sans code conditionnel.

Nirav Jain
la source
1
pourquoi 230, 999? Où obtenez-vous le numéro>
user4951
1
Le 230 peut être n'importe quel nombre. Il représente la largeur que vous souhaitez pour votre étiquette. Le 9999 que je préfère remplacer par INFINITY ou MAXFLOAT.
Florian Friedrich
La deuxième solution fonctionne comme un charme. Merci Nirav.
Jim
1
"[AppHandlers zHandler]" donne une erreur .. "Identificateurs non déclarés". Comment résoudre ça?
Dimple
9

Voici une solution simple:

Exigences :

CGSize maximumSize = CGSizeMake(widthHere, MAXFLOAT);
UIFont *font = [UIFont systemFontOfSize:sizeHere];

Maintenant que l' constrainedToSizeusage:lineBreakMode:utilisation est obsolète dans iOS 7.0 :

CGSize expectedSize = [stringHere sizeWithFont:font constrainedToSize:maximumSize lineBreakMode:NSLineBreakByWordWrapping];

Désormais, l'utilisation dans la version supérieure d' iOS 7.0 sera:

// Let's make an NSAttributedString first
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:stringHere];
//Add LineBreakMode
NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new];
[paragraphStyle setLineBreakMode:NSLineBreakByWordWrapping];
[attributedString setAttributes:@{NSParagraphStyleAttributeName:paragraphStyle} range:NSMakeRange(0, attributedString.length)];
// Add Font
[attributedString setAttributes:@{NSFontAttributeName:font} range:NSMakeRange(0, attributedString.length)];

//Now let's make the Bounding Rect
CGSize expectedSize = [attributedString boundingRectWithSize:maximumSize options:NSStringDrawingUsesLineFragmentOrigin context:nil].size;
Paresh Navadiya
la source
7

Vous trouverez ci-dessous deux méthodes simples qui remplaceront ces deux méthodes obsolètes.

Et voici les références pertinentes:

Si vous utilisez NSLineBreakByWordWrapping, vous n'avez pas besoin de spécifier le NSParagraphStyle, car c'est la valeur par défaut: https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSParagraphStyle_Class/index. html # // apple_ref / occ / clm / NSParagraphStyle / defaultParagraphStyle

Vous devez obtenir le plafond de la taille, pour correspondre aux résultats des méthodes obsolètes. https://developer.apple.com/library/ios/documentation/UIKit/Reference/NSString_UIKit_Additions/#//apple_ref/occ/instm/NSString/boundingRectWithSize:options:attributes:context :

+ (CGSize)text:(NSString*)text sizeWithFont:(UIFont*)font {    
    CGSize size = [text sizeWithAttributes:@{NSFontAttributeName: font}];
    return CGSizeMake(ceilf(size.width), ceilf(size.height));
}

+ (CGSize)text:(NSString*)text sizeWithFont:(UIFont*)font constrainedToSize:(CGSize)size{
    CGRect textRect = [text boundingRectWithSize:size
                                     options:NSStringDrawingUsesLineFragmentOrigin
                                  attributes:@{NSFontAttributeName: font}
                                     context:nil];
    return CGSizeMake(ceilf(textRect.size.width), ceilf(textRect.size.height));
}
Harris
la source
6

Dans la plupart des cas, j'ai utilisé la méthode sizeWithFont: constrainedToSize: lineBreakMode: pour estimer la taille minimale d'un UILabel pour accueillir son texte (en particulier lorsque l'étiquette doit être placée dans un UITableViewCell) ...

... Si c'est exactement votre situation, vous pouvez simplement utiliser la méthode:

CGSize size = [myLabel textRectForBounds:myLabel.frame limitedToNumberOfLines:mylabel.numberOfLines].size;

J'espère que cela pourrait aider.

roberto.buratti
la source
5
La documentation d'Apple indique que vous ne devez pas appeler cette méthode directement.
Barlow Tucker
Non mentionné dans la documentation du SDK iOS 7 au moins.
Rivera
3
UIFont *font = [UIFont boldSystemFontOfSize:16];
CGRect new = [string boundingRectWithSize:CGSizeMake(200, 300) options:NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName: font} context:nil];
CGSize stringSize= new.size;
user3575114
la source
3
Bienvenue dans StackOverFlow. Ne postez plus la même réponse. Si vous avez besoin d'ajouter quelque chose à une réponse, faites un commentaire ou modifiez la réponse.
Ramaraj T
ok..Je vais prendre cela en considération la prochaine fois. Merci pour vos conseils.
user3575114
2

[La réponse acceptée fonctionne bien dans une catégorie. J'écrase les noms de méthodes obsolètes. Est-ce une bonne idée? Semble fonctionner sans aucune plainte dans Xcode 6.x]

Cela fonctionne si votre cible de déploiement est 7.0 ou supérieure. La catégorie estNSString (Util)

NSString + Util.h

- (CGSize)sizeWithFont:(UIFont *) font;
- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size;

NSString + Util.m

- (CGSize)sizeWithFont:(UIFont *) font {
    NSDictionary *fontAsAttributes = @{NSFontAttributeName:font};
    return [self sizeWithAttributes:fontAsAttributes];
}

- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size {
    NSDictionary *fontAsAttributes = @{NSFontAttributeName:font};
    CGRect retVal = [self boundingRectWithSize:size
                                     options:NSStringDrawingUsesLineFragmentOrigin
                                  attributes:fontAsAttributes context:nil];
    return retVal.size;
}
Dan Rosenstark
la source
0
UIFont *font = [UIFont fontWithName:@"Courier" size:16.0f];

NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
paragraphStyle.lineBreakMode = NSLineBreakByTruncatingTail;
paragraphStyle.alignment = NSTextAlignmentRight;

NSDictionary *attributes = @{ NSFontAttributeName: font,
                    NSParagraphStyleAttributeName: paragraphStyle };

CGRect textRect = [text boundingRectWithSize:size
                                 options:NSStringDrawingUsesLineFragmentOrigin
                              attributes:attributes
                                 context:nil];

CGSize size = textRect.size;

à partir de deux réponses 1 + 2

Alex
la source