Conversion d'un projet d'iOS5.0 en iOS7/iOS6 sur Xcode 5. Le code ci-dessous donne un avertissement de temps de compilation:
'sizeWithFont: constrainedToSize: lineBreakMode:' est obsolète: d'abord obsolète dans ios 7.0 - Utilisation - boundingRectWithSize: options: attribut: contexte
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 0)
{
self.lblHidden.frame = CGRectMake(58, 228, 945, 9999);
self.lblHidden.text = detailShareObj.pDesc;
CGSize size = [detailShareObj.pDesc sizeWithFont:self.lblHidden.font constrainedToSize:self.lblHidden.frame.size lineBreakMode:NSLineBreakByWordWrapping];
return 228.0+size.height+20;
}
else if (indexPath.section == 1)
{
NSString *tempPointStr = (self.shortDescArray)[indexPath.row];
self.lblHidden.frame = CGRectMake(58, 0, 945, 9999);
self.lblHidden.text = tempPointStr;
CGSize size = [tempPointStr sizeWithFont:self.lblHidden.font
constrainedToSize:self.lblHidden.frame.size
lineBreakMode:NSLineBreakByWordWrapping];
return 50.0f;
}
J'ai essayé une partie de la suggestion donnée ailleurs mais rien n'est à sauver si quelqu'un peut aider en apportant les corrections requises dans le code sera grandement apprécié.
Je ne masquerais pas simplement l'avertissement de fonction obsolète. Ils l'ont déprécié pour une raison. Je crois que la fonction était obsolète parce que cette série de fonctions NSString + UIKit était basée sur la bibliothèque UIStringDrawing, qui n'était pas sûre pour les threads. Si vous avez essayé de les exécuter non pas sur le thread principal (comme toute autre fonctionnalité UIKit), vous obtiendrez des comportements imprévisibles. En particulier, si vous exécutez la fonction sur plusieurs threads simultanément, cela bloquera probablement votre application. C'est pourquoi dans iOS 6, ils ont introduit la méthode boundingRectWithSize:...
Pour NSAttributedStrings. Cela a été construit au-dessus des bibliothèques NSStringDrawing et est thread-safe.
Si vous regardez la nouvelle fonction NSString boundingRectWithSize:...
, Elle demande un tableau d'attributs de la même manière qu'un NSAttributeString. Si je devais deviner, cette nouvelle fonction NSString dans iOS 7 est simplement un wrapper pour la fonction NSAttributeString d'iOS 6.
Sur cette note, si vous ne preniez en charge que iOS 6 et iOS 7, je changerais certainement tous les sizeWithFont:...
De votre NSString en boundingRectWithSize
de NSAttributeString. Cela vous évitera beaucoup de maux de tête si vous avez un étui d'angle multi-threading étrange! Voici comment j'ai converti le sizeWithFont:constrainedToSize:
De NSString:
Ce qui était autrefois:
NSString *text = ...;
CGFloat width = ...;
UIFont *font = ...;
CGSize size = [text sizeWithFont:font
constrainedToSize:(CGSize){width, CGFLOAT_MAX}];
Peut être remplacé par:
NSString *text = ...;
CGFloat width = ...;
UIFont *font = ...;
NSAttributedString *attributedText =
[[NSAttributedString alloc]
initWithString:text
attributes:@
{
NSFontAttributeName: font
}];
CGRect rect = [attributedText boundingRectWithSize:(CGSize){width, CGFLOAT_MAX}
options:NSStringDrawingUsesLineFragmentOrigin
context:nil];
CGSize size = rect.size;
Veuillez noter que la documentation mentionne:
Dans iOS 7 et versions ultérieures, cette méthode renvoie des tailles fractionnaires (dans le composant de taille du CGRect renvoyé); pour utiliser une taille renvoyée à des vues de taille, vous devez utiliser augmenter sa valeur à l'entier supérieur le plus proche à l'aide de la fonction ceil.
Donc, pour extraire la hauteur ou la largeur calculée à utiliser pour dimensionner les vues, j'utiliserais:
CGFloat height = ceilf(size.height);
CGFloat width = ceilf(size.width);
Si vous le souhaitez compatible avec iOS7 et les versions inférieures, essayez celui-ci (avec ARC):
CGSize size;
if ([tempPointStr respondsToSelector:
@selector(boundingRectWithSize:options:attributes:context:)])
{
NSMutableParagraphStyle * paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
paragraphStyle.alignment = NSTextAlignmentLeft;
NSDictionary * attributes = @{NSFontAttributeName : self.lblHidden.font,
NSParagraphStyleAttributeName : paragraphStyle};
size = [tempPointStr boundingRectWithSize:self.lblHidden.frame.size
options:NSStringDrawingUsesFontLeading
|NSStringDrawingUsesLineFragmentOrigin
attributes:attributes
context:nil].size;
} else {
#pragma clang diagnostic Push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
size = [tempPointStr sizeWithFont:self.lblHidden.font
constrainedToSize:self.lblHidden.frame.size
lineBreakMode:NSLineBreakByWordWrapping];
#pragma clang diagnostic pop
}
Note: Ce n'est qu'un exemple pour votre else-if
cas, vous devrez peut-être faire quelques modifications selon ce que vous voulez. ;)
Pour iOS7, remplacez:
CGSize size = [tempPointStr sizeWithFont:self.lblHidden.font
constrainedToSize:self.lblHidden.frame.size
lineBreakMode:NSLineBreakByWordWrapping];
Avec:
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc]init];
paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping; //set the line break mode
NSDictionary *attrDict = [NSDictionary dictionaryWithObjectsAndKeys:self.lblHidden.font, NSFontAttributeName, paragraphStyle, NSParagraphStyleAttributeName, nil];
CGSize size = [tempPointStr boundingRectWithSize:self.lblHidden.frame.size
options:NSStringDrawingTruncatesLastVisibleLine|NSStringDrawingUsesLineFragmentOrigin
attributes:attrDict context:nil].size;
Vous pouvez utiliser:
UIFont *font = [UIFont boldSystemFontOfSize:16];
CGRect new = [string boundingRectWithSize:CGSizeMake(200, 300)
options:NSStringDrawingUsesFontLeading
attributes:@{NSFontAttributeName: font}
context:nil];
CGSize stringSize= new.size;
Le contexte boundingRectWithSize: options: attributes: a le problème de ne pas calculer correctement la hauteur si la chaîne contient "\ n" (sauts de ligne). Par conséquent, ce code calcule la taille de chaque ligne séparément pour une largeur donnée (inWidth):
NSArray *brokenByLines=[string componentsSeparatedByString:@"\n"];
CGFloat height=0.0;
CGFloat maxWidth=0.0;
for (NSString* actString in brokenByLines) {
CGRect tSize=[actString boundingRectWithSize:CGSizeMake(inWidth, 600) options:(NSStringDrawingUsesLineFragmentOrigin | NSLineBreakByWordWrapping) attributes:@{NSFontAttributeName: inFont} context:nil];
if (maxWidth<tSize.size.width) {
maxWidth=tSize.size.width;
}
height+=tSize.size.height;
}
CGSize size= CGSizeMake(ceil(maxWidth), ceil(height));
Si vous ciblez iOS 6.0+, vous pouvez toujours utiliser sizeWithFont:constrainedToSize:lineBreakMode:
. Assurez-vous simplement que iOS Deployment Target
est défini sur 6.0 et le compilateur ne vous donnera pas ces avertissements.
(Vous pouvez le trouver en cliquant sur l'onglet bleu du projet (généralement en haut à gauche, volet du navigateur de projet) dans la section "info").
Si vous ciblez uniquement iOS 7.0+, vous devez utiliser la nouvelle méthode boundingRectWithSize:options:attributes:context
.
Vous pouvez trouver les documents Apple sur cette nouvelle méthode ici.