Reemplazo para -sizeWithFont en desuso: restringinedToSize: lineBreakMode: en iOS 7?

146

En iOS 7, el método:

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

y el método:

- (CGSize)sizeWithFont:(UIFont *)font

están en desuso. ¿Cómo puedo reemplazar

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

y:

CGSize size = [string sizeWithFont:font];
user_Dennis_Mostajo
fuente
2
El método sustituto es -sizeWithAttributes:.
holex
ok holex gracias pero, ¿cómo puedo usar una fuente de la etiqueta como un NSDIctionary? si mi código es como: sizeWithFont: customlabel.font; el vacío preguntar "sizeWithAttributes: <# (NSDictionary *) #>"
user_Dennis_Mostajo
1
Aquí está la documentación oficial de cómo puede definir los atributos: developer.apple.com/library/ios/documentation/UIKit/Reference/…
holex

Respuestas:

219

Podrías probar esto:

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

CGSize size = textRect.size;

Simplemente cambie "FONT" por una "[fuente UIFont ...]"

Xavier Maroñas
fuente
13
¿Y dónde mencionas NSLineBreakByWordWrapping? ¿Dónde se fue?
user4951
32
NSLineBreakByWordWrappingiría dentro de a NSParagraphStyle. Entonces, por ejemplo: NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;en los atributos que necesitaría agregar NSParagraphStyleAttributeName: paragraphStyle.copy...
Florian Friedrich
1
@ffried en mi caso al agregar el párrafoStyle con un salto de línea que no sea NSLineBreakByWordWrapping, el tamaño se calculó para una sola línea ... ¿Alguna idea?
manicaesar 03 de
9
No olvide que boundingRectWithSize:options:attributes:context:devuelve valores fraccionarios. Debe hacer ceil(textRect.size.height)y ceil(textRect.size.width)respectivamente para obtener la altura / anchura real.
Florian Friedrich
20
¿Qué diablos es BOLIVIASize?
JRam13
36

Como no podemos usar sizeWithAttributes para todos los iOS superiores a 4.3, tenemos que escribir código condicional para 7.0 y iOS anteriores.

1) Solución 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) Solución 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 primera solución es en algún momento no devolver el valor adecuado de altura. entonces usa otra solución. que funcionará perfectamente

La segunda opción está bastante bien y funciona sin problemas en todos los iOS sin código condicional.

Nirav Jain
fuente
1
¿Por qué 230, 999? ¿Dónde se obtiene el número>
user4951
1
El 230 puede ser cualquier número. Representa el ancho que desea para su etiqueta. El 9999 prefiero reemplazarlo con INFINITY o MAXFLOAT.
Florian Friedrich
La segunda solución es trabajar como un encanto. Gracias Nirav
Jim
1
"[AppHandlers zHandler]" da un error .. "Identificadores no declarados". ¿Cómo resolver eso?
Hoyuelo
9

Aquí hay una solución simple:

Requisitos:

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

Ahora como el constrainedToSizeusage:lineBreakMode:uso está en desuso en iOS 7.0 :

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

Ahora el uso en una versión mayor de iOS 7.0 será:

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

A continuación hay dos métodos simples que reemplazarán estos dos métodos obsoletos.

Y aquí están las referencias relevantes:

Si está utilizando NSLineBreakByWordWrapping, no necesita especificar NSParagraphStyle, ya que ese es el valor predeterminado: https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSParagraphStyle_Class/index. html # // apple_ref / occ / clm / NSParagraphStyle / defaultParagraphStyle

Debe obtener el límite máximo del tamaño para que coincida con los resultados de los métodos obsoletos. 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
fuente
6

En la mayoría de los casos, utilicé el método sizeWithFont: restrictinedToSize: lineBreakMode: para estimar el tamaño mínimo para que un UILabel acomode su texto (especialmente cuando la etiqueta debe colocarse dentro de UITableViewCell) ...

... Si esta es exactamente su situación, simplemente puede usar el método:

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

Espero que esto pueda ayudar.

roberto.buratti
fuente
55
La documentación de Apple dice que no debe llamar a este método directamente.
Barlow Tucker
No se menciona en la documentación del SDK de iOS 7 al menos.
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;
usuario3575114
fuente
3
Bienvenido a StackOverFlow. No publique una misma respuesta nuevamente. Si necesita agregar algo a una respuesta, haga un comentario o edite la respuesta.
Ramaraj T
ok..lo tendré en cuenta la próxima vez. Gracias por tu consejo.
user3575114
2

[La respuesta aceptada funciona bien en una categoría. Estoy sobrescribiendo los nombres de métodos obsoletos. ¿Es esta una buena idea? Parece funcionar sin quejas en Xcode 6.x]

Esto funciona si su objetivo de implementación es 7.0 o superior. La categoría esNSString (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
fuente
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;

de dos respuestas 1 + 2

Alex
fuente