web-dev-qa-db-fra.com

'sizeWithFont: constrainedToSize: lineBreakMode:' est déconseillé:

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é.

29
iSrini

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);
64
Mr. T

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. ;)

44
Kjuly

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;
10
Dave Chambers

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;
2
user3575114

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));
1
EckhardN

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.

1
JRG-Developer