Aquí está mi fragmento de código de trabajo:
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:attributeDict];
NSString *headline = [dict objectForKey:@"title"];
UIFont *font = [UIFont boldSystemFontOfSize:18];
CGRect rect = [headline boundingRectWithSize:CGSizeMake(300, 1000) options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:font} context:nil];
CGFloat height = roundf(rect.size.height +4)
Agregué 4px a la altura calculada, porque sin estos 4px, falta una línea.
Utilizo este fragmento de código en un tableView y agrego la "altura" a una matriz de NSNumbers y obtengo la altura de celda correcta para la etiqueta de texto predeterminada.
Agregue 4 píxeles más si desea más espacio debajo del texto en la etiqueta de texto.
**** ACTUALIZACIÓN ****
No estoy de acuerdo con el "error de ancho de 40px", grito que sean los 4px de altura que faltan, porque 4px es la altura predeterminada de un espacio entre una letra y el límite de una sola línea. Puede comprobarlo con una UILabel, para un tamaño de fuente de 16 necesita una altura de UILabel de 20.
Pero si su última línea no tiene "g" o lo que sea, la medición podría perder los 4px de altura.
Lo volví a verificar con un pequeño método, obtengo una altura precisa de 20,40 o 60 para mi etiqueta y un ancho correcto de menos de 300px.
Para admitir iOS6 e iOS7, puede usar mi método:
- (CGFloat)heightFromString:(NSString*)text withFont:(UIFont*)font constraintToWidth:(CGFloat)width
{
CGRect rect;
float iosVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
if (iosVersion >= 7.0) {
rect = [text boundingRectWithSize:CGSizeMake(width, 1000) options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:font} context:nil];
}
else {
CGSize size = [text sizeWithFont:font constrainedToSize:CGSizeMake(width, 1000) lineBreakMode:NSLineBreakByWordWrapping];
rect = CGRectMake(0, 0, size.width, size.height);
}
NSLog(@"%@: W: %.f, H: %.f", self, rect.size.width, rect.size.height);
return rect.size.height;
}
**** POTENCIAR ****
Gracias a sus comentarios, actualicé mi función de la siguiente manera. Dado que sizeWithFont está en desuso y recibirá una advertencia en XCode, agregué el diagnóstico-pragma-code para eliminar la advertencia para esta función / bloque de código en particular.
- (CGFloat)heightFromStringWithFont:(UIFont*)font constraintToWidth:(CGFloat)width
{
CGRect rect;
if ([self respondsToSelector:@selector(boundingRectWithSize:options:attributes:context:)]) {
rect = [self boundingRectWithSize:CGSizeMake(width, 1000) options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:font} context:nil];
}
else {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
CGSize size = [self sizeWithFont:font constrainedToSize:CGSizeMake(width, 1000) lineBreakMode:NSLineBreakByWordWrapping];
rect = CGRectMake(0, 0, size.width, size.height);
#pragma GCC diagnostic pop
}
return ceil(rect.size.height);
}
Además del tema 4px: dependiendo de la fuente y el peso de la fuente que use, el cálculo devuelve diferentes valores de altura. En mi caso: HelveticaNeue-Medium con un tamaño de fuente de 16.0 devuelve una altura de línea de 20.0 para una sola línea pero 39.0 para dos líneas, 78px para 4 líneas -> falta 1px para cada línea - comenzando con la línea 2 - pero quieres para tener su tamaño de fuente + espacio de línea de 4px para cada línea, debe obtener un resultado de altura.
¡Tenga esto en cuenta mientras codifica!
Todavía no tengo una función para este "problema" pero actualizaré esta publicación cuando termine.