2009-07-30 9 views
5

Estoy tratando de medir el tamaño visual de un NSString que tenga en cuenta el número de líneas que puedo representar. Sin embargo, sizeWithFont no tiene en cuenta la propiedad numberOfLines? Entonces, mi algoritmo de diseño coloca todo lo más bajo de lo que realmente necesitan ser.iPhone UILabel sizeWithFont:

_price = [[UILabel alloc] init]; 
_price.text = myPriceValue; 
_price.lineBreakMode = UILineBreakModeWordWrap; 
_price.numberOfLines = 3; 
_price.backgroundColor = [UIColor clearColor]; 
_price.textColor = TTSTYLEVAR(colorPrice); 
/// the follow code ignores numberOfLines and just tells me the size of the whole block. 
// I'd like it to be aware of numberOfLines 
// 
CGSize priceSize = [_price.text sizeWithFont:_price.font 
     constrainedToSize:CGSizeMake(maxWidth, CGFLOAT_MAX) 
     lineBreakMode:UILineBreakModeWordWrap]; 

¿Alguien sabe cómo hacer esto con el iPhone SDK?

Respuesta

12

En lugar de CGFLOAT_MAX para la altura máxima del cálculo de texto, trate de conseguir el tamaño de una línea con esto:

[_price.text sizeWithFont:_price.font].height 

y luego multiplicando por el máximo # de líneas que desea, a continuación, conectarlo de que en la altura del tamaño al que se está limitando. Probablemente vería así:

_price = [[UILabel alloc] init]; 
_price.text = myPriceValue; 
_price.lineBreakMode = UILineBreakModeWordWrap; 
_price.numberOfLines = 3; 
_price.backgroundColor = [UIColor clearColor]; 
_price.textColor = TTSTYLEVAR(colorPrice); 
CGFloat lineHeight = [_price.text sizeWithFont:_price.font].height; 
CGSize priceSize = [_price.text sizeWithFont:_price.font 
     constrainedToSize:CGSizeMake(maxWidth, lineHeight * _price.numberOfLines) 
     lineBreakMode:UILineBreakModeWordWrap]; 

No utilice este si alguna vez configurar el número de líneas a 0 como su altura máxima será 0, en ese caso; Deberías usar CGFLOAT_MAX entonces.

+2

sizeWithFont está en desuso en iOS7 y se debe usar boundingRectWithSize en su lugar. –

-1

Por supuesto, no lo tiene en cuenta, ya que nada que se llame o haya pasado tiene esa información. Estás trabajando estrictamente con cadenas, tamaños y fuentes. Es la etiqueta que tiene el número de líneas.

No estoy seguro de cuál es exactamente su problema; ¿Estás obteniendo un tamaño que es demasiado alto o demasiado corto, o qué? Puede averiguar el número de líneas de texto dividiendo la altura del resultado por la altura de la fuente, que es el valor del ascendente más el descendente, creo.

+0

En realidad, sizeWithFont: constainedToSize: lineBreakMode tiene en cuenta un cuadro delimitador y el ajuste de texto. Tenga en cuenta que sizeWithFont: forWidth: lineBreakMode NO funciona con varias líneas. –

0

En lugar de tratar de hacerlo en una sola llamada, hacer algo como esto (perdón por el pseudocódigo, es tarde):

NSString *s = _price.text; 
UIFont *font = _price.font; 
CGFloat fontSize = font.pointSize; 

while (TRUE) 
{ 
    CGSize priceSize = [s sizeWithFont: font constrainedToSize: 
     CGSizeMake(maxWidth, fontSize) lineBreakMode: UILineBreakModeWordWrap]; 

    if (/* priceSize is satisfactory */) 
    { 
     break; // Make sure this exits, eventually!!! 
    } 
    fontSize -= 1.0; // or a smaller decrement if you like 
    font = // new, smaller font 

} 
0

La respuesta correcta es, por supuesto, tiene que establecer numberOfLines a 0, lo que hará que el marco calcule el resultado con la cantidad de líneas que necesite. Vea también this question.

+0

No, el número de líneas a 0 es líneas infinitas. pero quiero la altura de 3 líneas – CVertex

+0

Ah, ya veo. Yo malentendí la pregunta. –

5

Use sizeToFit de UILabel en lugar de sizeWithFont: para diseñar un UILabel de varias líneas, ya que sizeWithFont: truncará la cadena (vea Apple Docs). El siguiente código reduce el tamaño de fuente de una etiqueta hasta que el ajuste de texto en un tamaño especificado ... varias líneas de texto se utilizará tan pronto como se encajan en la altura especificada:

-(void)setFontSizeOfMultiLineLabel: (UILabel*)label 
     toFitSize: (CGSize) size 
     forMaxFontSize: (CGFloat) maxFontSize 
     andMinFontSize: (CGFloat) minFontSize 
     startCharacterWrapAtSize: (CGFloat)characterWrapSize{ 

CGRect constraintSize = CGRectMake(0, 0, size.width, 0); 
label.frame = constraintSize; 
label.lineBreakMode = UILineBreakModeWordWrap; 
label.numberOfLines = 0; // allow any number of lines 

for (int i = maxFontSize; i > minFontSize; i--) { 

    if((i < characterWrapSize) && (label.lineBreakMode == UILineBreakModeWordWrap)){ 
     // start over again with lineBreakeMode set to character wrap 
     i = maxFontSize; 
     label.lineBreakMode = UILineBreakModeCharacterWrap; 
    } 

    label.font = [label.font fontWithSize:i]; 
    [label sizeToFit]; 
    if(label.frame.size.height < size.height){ 
     break; 
    }  
    label.frame = constraintSize; 
    } 
} 

Call esto con una etiqueta que tiene su texto favorito y la fuente:

UILabel *label = [[UILabel alloc] initWithFrame: CGRectZero]; 
label.backgroundColor = [UIColor clearColor]; 
label.textColor = [UIColor whiteColor]; 
label.text = text; 
label.font = [UIFont fontWithName: @"Helvetica" size: 16]; 
[self setFontSizeOfMultiLineLabel: label toFitSize: CGSizeMake(200, 44) forMaxFontSize: 16 andMinFontSize: 8 startCharacterWrapAtSize: 11]; 

el parámetro startCharacterWrapAtSize le permite elegir utilizar characterWrap empezando por el tamaño de la fuente dando. Esto debería ahorrar espacio en el caso de que WordWrap usara fuentes realmente pequeñas.

edición: corrección de errores

+0

Esto también funcionaría bien como una categoría en 'UILabel' –

Cuestiones relacionadas