2010-08-19 10 views
5

Esto es parte de una aplicación de iPhone pero debe aplicarse a Cocoa escrito en objC en general.Cambiar el tamaño de UILabel para que quepa con Word Wrap

Tengo un UILabel con varias cantidades de texto (de caracteres individuales a varias oraciones). El texto siempre debe mostrarse en la fuente más grande posible que se ajuste a todo el texto dentro de UILabel. El número máximo de líneas se establece en 4 y el modo de salto de línea se establece en ajuste de palabras.

Como se usan varias líneas, ajustaFontSizeToFitWidth no funcionará para cambiar el tamaño del texto.

Así que estoy usando un bucle para determinar el mayor tamaño de la fuente posible para cada cadena como por ejemplo:

//Set the text 
    self.textLabel.text = text; 
    //Largest size used 
    NSInteger fsize = 200; textLabel.font = [UIFont 
    fontWithName:@"Verdana-Bold" 
    size:fsize]; 

    //Calculate size of the rendered string with the current parameters 
    float height = [text sizeWithFont:textLabel.font 
     constrainedToSize:CGSizeMake(textLabel.bounds.size.width,99999) 
     lineBreakMode:UILineBreakModeWordWrap].height; 

    //Reduce font size by 5 while too large, break if no height (empty string) 
    while (height > textLabel.bounds.size.height and height != 0) { 
     fsize -= 5; 
     textLabel.font = [UIFont fontWithName:@"Verdana-Bold" size:fsize]; 
     height = [text sizeWithFont:textLabel.font 
      constrainedToSize:CGSizeMake(textLabel.bounds.size.width,99999) 
      lineBreakMode:UILineBreakModeWordWrap].height; 
    }; 

Este enfoque funciona bien en su mayor parte. La excepción son palabras largas. Tomemos la cadena @ "La experiencia foo". como ejemplo. La palabra "experiencia", que es mucho más larga que las demás, se dividirá por la mitad sin que se envuelva la palabra correctamente y la secuencia se dividirá en 4 líneas. Estoy buscando una manera de reducir el tamaño aún más para que cada palabra individual se ajuste en una línea.

Ejemplo:

-old-

tamaño de letra: 60

The 
Exper 
ience 
foo 

debería ser

-NEW-

tamaño de letra: 30

The 
Experience 
foo 

Probablemente es una manera fácil de hacer esto, pero estoy golpeando una pared.

Respuesta

11

Aquí es la forma más elegante (aunque algo hacker) que he encontrado para hacer este trabajo:

  1. dividir la cadena en palabras
  2. calcular el ancho de cada palabra utilizando el tamaño de fuente actual
  3. Reducir el tamaño de la cadena hasta que cada palabra se inscribe en una línea

el consumo de recursos es lo suficientemente bajo como para que esto funcione incluso en UITableViews llena de cadenas edi ted de esta manera.

Este es el código nuevo:

//Set the text 
self.textLabel.text = text; 
//Largest size used 
NSInteger fsize = 200; textLabel.font = [UIFont fontWithName:@"Verdana-Bold" 
                 size:fsize]; 

//Calculate size of the rendered string with the current parameters 
float height = 
     [text sizeWithFont:textLabel.font 
     constrainedToSize:CGSizeMake(textLabel.bounds.size.width,99999) 
      lineBreakMode:UILineBreakModeWordWrap].height; 

//Reduce font size by 5 while too large, break if no height (empty string) 
while (height > textLabel.bounds.size.height and height != 0) { 
    fsize -= 5; 
    textLabel.font = [UIFont fontWithName:@"Verdana-Bold" size:fsize]; 
    height = [text sizeWithFont:textLabel.font 
       constrainedToSize:CGSizeMake(textLabel.bounds.size.width,99999) 
        lineBreakMode:UILineBreakModeWordWrap].height; 
}; 

// Loop through words in string and resize to fit 
for (NSString *word in [text componentsSeparatedByString:@" "]) { 
    float width = [word sizeWithFont:textLabel.font].width; 
    while (width > textLabel.bounds.size.width and width != 0) { 
     fsize -= 3; 
     textLabel.font = [UIFont fontWithName:@"Verdana-Bold" size:fsize]; 
     width = [word sizeWithFont:textLabel.font].width; 

    } 
} 
+0

porque 'sizeWithFont:' se ha vuelto obsoleto con iOS 7, que debiera reemplácelo por 'boundingRectWithSize:'. – AppsolutEinfach

3

Usted puede utilizar el código anterior en una Categoría para UILabel

UILabel + AdjustFontSize.h

@interface UILabel (UILabel_AdjustFontSize) 

- (void) adjustsFontSizeToFitWidthWithMultipleLinesFromFontWithName:(NSString*)fontName size:(NSInteger)fsize andDescreasingFontBy:(NSInteger)dSize; 

@end 

UILabel + AdjustFontSize.m

@implementation UILabel (UILabel_AdjustFontSize) 

- (void) adjustsFontSizeToFitWidthWithMultipleLinesFromFontWithName:(NSString*)fontName size:(NSInteger)fsize andDescreasingFontBy:(NSInteger)dSize{ 

    //Largest size used 
    self.font = [UIFont fontWithName:fontName size:fsize]; 

    //Calculate size of the rendered string with the current parameters 
    float height = [self.text sizeWithFont:self.font 
        constrainedToSize:CGSizeMake(self.bounds.size.width,99999) 
         lineBreakMode:UILineBreakModeWordWrap].height; 

    //Reduce font size by dSize while too large, break if no height (empty string) 
    while (height > self.bounds.size.height && height != 0) { 
     fsize -= dSize; 
     self.font = [UIFont fontWithName:fontName size:fsize]; 
     height = [self.text sizeWithFont:self.font 
        constrainedToSize:CGSizeMake(self.bounds.size.width,99999) 
         lineBreakMode:UILineBreakModeWordWrap].height; 
    }; 

    // Loop through words in string and resize to fit 
    for (NSString *word in [self.text componentsSeparatedByString:@" "]) { 
     float width = [word sizeWithFont:self.font].width; 
     while (width > self.bounds.size.width && width != 0) { 
      fsize -= dSize; 
      self.font = [UIFont fontWithName:fontName size:fsize]; 
      width = [word sizeWithFont:self.font].width;    
     } 
    } 
} 

@end 
+1

Intentó su código, entra en un bucle infinito en la instrucción while. – Resh32

3

Ésta es mi versión de la respuesta de 0x90 en la categoria:

@implementation UILabel (MultilineAutosize) 

- (void)adjustFontSizeToFit 
{ 
    //Largest size used 
    NSInteger fsize = self.font.pointSize; 

    //Calculate size of the rendered string with the current parameters 
    float height = [self.text sizeWithFont:self.font 
         constrainedToSize:CGSizeMake(self.bounds.size.width, MAXFLOAT) 
          lineBreakMode:NSLineBreakByWordWrapping].height; 

    //Reduce font size by 5 while too large, break if no height (empty string) 
    while (height > self.bounds.size.height && height > 0) { 
     fsize -= 5; 
     self.font = [self.font fontWithSize:fsize]; 
     height = [self.text sizeWithFont:self.font 
         constrainedToSize:CGSizeMake(self.bounds.size.width, MAXFLOAT) 
          lineBreakMode:NSLineBreakByWordWrapping].height; 
    }; 

    // Loop through words in string and resize to fit 
    for (NSString *word in [self.text componentsSeparatedByString:@" "]) { 
     float width = [word sizeWithFont:self.font].width; 
     while (width > self.bounds.size.width && width > 0) { 
      fsize -= 3; 
      self.font = [self.font fontWithSize:fsize]; 
      width = [word sizeWithFont:self.font].width; 
     } 
    } 
} 

@end 
Cuestiones relacionadas