Sostituzione per deprecato -sizeWithFont: vincoloToSize: lineBreakMode: in iOS 7?


146

In iOS 7, il metodo:

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

e il metodo:

- (CGSize)sizeWithFont:(UIFont *)font

sono deprecati. Come posso sostituire

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

e:

CGSize size = [string sizeWithFont:font];

2
il metodo sostitutivo è -sizeWithAttributes:.
Holex,

ok holex grazie ma, come posso usare un font da etichetta come un NSDIctionary? se il mio codice è come: sizeWithFont: customlabel.font; il vuoto chiede "sizeWithAttributes: <# (NSDictionary *) #>"
user_Dennis_Mostajo

1
ecco la documentazione ufficiale su come definire gli attributi: developer.apple.com/library/ios/documentation/UIKit/Reference/…
holex

Risposte:


219

Puoi provare questo:

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

CGSize size = textRect.size;

Basta cambiare "FONT" per un "[carattere UIFont ....]"


13
E dove menzioni NSLineBreakByWordWrapping? Dov'è finito?
user4951

32
NSLineBreakByWordWrappingandrebbe dentro a NSParagraphStyle. Quindi, per esempio: NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;negli attributi dovresti aggiungere NSParagraphStyleAttributeName: paragraphStyle.copy...
Florian Friedrich,

1
@ffried nel mio caso l'aggiunta del paragrafo Style con interruzione di riga diversa da NSLineBreakByWordWrapping ha comportato il calcolo delle dimensioni per una sola riga ... Qualche idea?
manicaesar,

9
Non dimenticare che boundingRectWithSize:options:attributes:context:restituisce valori frazionari. Devi fare ceil(textRect.size.height)e ceil(textRect.size.width)rispettivamente per ottenere la vera altezza / larghezza.
Florian Friedrich,

20
Che diamine è BOLIVIASize?
JRam13

36

Poiché non possiamo usare sizeWithAttributes per tutti i iOS superiori a 4.3, dobbiamo scrivere un codice condizionale per 7.0 e iOS precedenti.

1) Soluzione 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) Soluzione 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];

A volte la prima soluzione non riesce a restituire il valore corretto dell'altezza. quindi usa un'altra soluzione. che funzionerà perfettamente.

La seconda opzione è abbastanza buona e funziona senza problemi in tutti i dispositivi iOS senza codice condizionale.


1
perché 230, 999? Dove ottieni il numero>
user4951

1
Il 230 può essere qualsiasi numero. Rappresenta la larghezza desiderata per l'etichetta. Il 9999 preferirei sostituire con INFINITY o MAXFLOAT.
Florian Friedrich,

La seconda soluzione sta funzionando come un fascino. Grazie Nirav.
Jim,

1
"[AppHandlers zHandler]" restituisce un errore. "Identificatori non dichiarati". Come risolverlo?
Dimple

9

Ecco una soluzione semplice:

Requisiti :

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

Ora poiché l' constrainedToSizeusage:lineBreakMode:utilizzo è obsoleto in iOS 7.0 :

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

Ora l'utilizzo in una maggiore versione di iOS 7.0 sarà:

// 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;

7

Di seguito sono riportati due semplici metodi che sostituiranno questi due metodi obsoleti.

Ed ecco i riferimenti rilevanti:

Se si utilizza NSLineBreakByWordWrapping, non è necessario specificare NSParagraphStyle, poiché è quello predefinito: https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSParagraphStyle_Class/index. html # // apple_ref / OCC / CLM / NSParagraphStyle / defaultParagraphStyle

È necessario ottenere il ceil della dimensione, affinché corrisponda ai risultati dei metodi obsoleti. 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));
}

6

Nella maggior parte dei casi ho usato il metodo sizeWithFont: VincoloConfigurazione: lineBreakMode: per stimare la dimensione minima per un UILabel per al suo testo (specialmente quando l'etichetta deve essere collocata all'interno di un UITableViewCell) ...

... Se questa è esattamente la tua situazione, puoi semplicemente utilizzare il metodo:

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

Spero che questo possa aiutare.


5
La documentazione di Apple afferma che non dovresti chiamare questo metodo direttamente.
Barlow Tucker,

Almeno non menzionato nella documentazione dell'SDK per iOS 7.
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;

3
Benvenuto in StackOverFlow. Non pubblicare di nuovo una stessa risposta. Se devi aggiungere qualcosa a una risposta, fai un commento o fai una modifica alla risposta.
Ramaraj T

ok.. lo terrò in considerazione la prossima volta. Grazie per il tuo consiglio.
user3575114,

2

[La risposta accettata funziona bene in una categoria. Sto sovrascrivendo i nomi dei metodi deprecati. E 'questa una buona idea? Sembra funzionare senza lamentele in Xcode 6.x]

Funziona se il target di distribuzione è 7.0 o superiore. La categoria èNSString (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;
}

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;

da due risposte 1 + 2

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.