2009-01-18 9 views
37

En mi pregunta "How do I get -[NSString sizeWithFont:forWidth:lineBreakMode:] to work?", me enteré de que -[NSString sizeWithFont:constrainedToSize:lineBreakMode:] era realmente lo que necesitaba.¿Qué es - [NSString sizeWithFont: forWidth: lineBreakMode:] bueno para?

La documentación para los estados -[NSString sizeWithFont:forWidth:lineBreakMode:] explica que en realidad no ajusta el texto a líneas adicionales. Entonces, ¿cómo lo usaría? (Los ejemplos ayudarían.)

Respuesta

66

Funciona muy bien para cadenas de varias líneas también.

Básicamente es una función que le permite ver qué tan grande va a ser una cuerda cuando se procesa con un modo de fuente y salto de línea.

Lo uso en algunos puntos en mi aplicación cuando tengo texto de longitud variable que quiero mostrar en un área determinada.

Por defecto, UILabel centrará el texto verticalmente. Para alinear el texto, es necesario que el tamaño de la etiqueta sea el alto requerido por la cadena que contiene.

Utilizo este método para hacer esto.

Y ejemplo de cómo lo usaría para hacer eso es como sigue:

//Calculate the expected size based on the font and linebreak mode of your label 
CGSize maximumLabelSize = CGSizeMake(296,9999); 

CGSize expectedLabelSize = [yourString sizeWithFont:yourLabel.font 
         constrainedToSize:maximumLabelSize 
         lineBreakMode:yourLabel.lineBreakMode]; 

//adjust the label the the new height. 
CGRect newFrame = yourLabel.frame; 
newFrame.size.height = expectedLabelSize.height; 
yourLabel.frame = newFrame; 

Se especifica qué tan grande de un área que tiene que poner el texto, y luego este método le indica la cantidad de espacio ocupará (envolviendo según sea necesario). Además, si la cadena se desbordará en los límites de la recta que proporcione, podrá saber y luego decidir cómo mostrar el texto.

La referencia a que no está envolviendo el texto está allí porque este método no le hace nada al texto. Simplemente lo establece y devuelve la cantidad de área que necesitaría para diseñarlo.

es responsabilidad de la etiqueta (o del contenedor que esté utilizando para el texto) realizar la envoltura/lo que sea que deba hacerse.

Espero que ayude.

chris.

+0

newFrame.size.height = maximumLabelSize .height; SB: newFrame.size.height = expectedLabelSize.height; – JoBu1324

+0

funciona incluso cuando dibujas un rect! – tipycalFlow

2

Parece que sería bueno para etiquetas de una sola línea. Por ejemplo, si está dibujando una cadena que puede estar truncada o tener un salto de línea, pero en realidad no dibujará más de una línea. Todavía podría ser útil saber la altura y el ancho exactos de la cadena, para que pueda ubicarla exactamente donde la desea (y dibujar otros elementos de la interfaz de usuario a su alrededor).

25

Por un tiempo pensé que esta rutina simplemente se había roto. Parece que es la rutina perfecta para trabajar cómo alto una pieza de texto, cuando se envuelve en un determinado ancho. Sin embargo, esto no es lo que hace. De hecho, la altura devuelta es siempre una sola línea. (Lo cual no tiene sentido, por cierto:. UIFont 's -leading devuelve el mismo valor)

Para citar la documentación en el momento de la escritura:

A pesar de que calcula dónde ocurrirán los saltos de línea, este método no hace en realidad, envuelve el texto en líneas adicionales; [...]

Esta frase me confundió por un largo tiempo.Mis pensamientos corrieron a lo largo de las líneas de:

  • Compilando saltos de línea, pero no envolviendo. Eh?
  • ¿Quizás signifiquen que la recepción NSString no se mutará para reflejar saltos de línea? Pero no espero eso de todos modos?
  • Esta oración no es coherente consigo misma. No tengo más remedio que ignorarlo.

Sin embargo, resulta que hay un significado que coincide con el comportamiento que vemos. Parece que lo que quieren decir es:

Esta rutina calculará donde ocurrirá la primera salto de línea, y todo el texto después de esto se tiene en cuenta a los efectos del cálculo del cuadro delimitador.

El cuadro delimitador devuelto tendrá, por lo tanto, la altura de una sola línea y un ancho hasta el máximo especificado. (El ancho puede ser menor dependiendo de dónde se calcula el salto de línea, o si el texto es lo suficientemente corto como para que no necesite el ancho máximo.)

Para, um, responder la pregunta real: ¿Qué es bueno? ¿para? No he encontrado nada útil: solo cosas donde pensé que sería útil, pero no lo era. Algunas cosas que le vienen a la mente, sin embargo, son:

  • Centrando un texto de una sola línea. Estoy pensando en botones y/o títulos aquí. (Aunque UILabel y UIButton pueden hacerlo, a veces usted mismo quiere dibujarlo).
  • Cálculo de los límites para un "extracto" de una pieza de texto más larga. Aquí estoy pensando en dónde podría querer mostrar un fragmento de una pieza de texto mucho más grande.
+2

+1 para la pregunta brutalmente honesta "¿para qué sirve?" Sí, he tenido el mismo pensamiento. De todos modos, suena como NSString sizeWithFont: constrainedToSize: lineBreakMode es lo que necesito. Gracias – Chris

1

Aquí hay algo que se me ocurrió después de aplicar algunos principios del ejemplo de PyjamaSam:

AnnotationPin *myAnnotation = (AnnotationPin *)annotation; 

self = [super initWithAnnotation:myAnnotation reuseIdentifier:reuseIdentifier]; 
self.backgroundColor = [UIColor greenColor]; 
self.frame = CGRectMake(0,0,30,30); 
imageView = [[UIImageView alloc] initWithImage:myAnnotation.THEIMAGE]; 
imageView.frame = CGRectMake(3,3,20,20); 
imageView.layer.masksToBounds = NO; 
[self addSubview:imageView]; 
[imageView release]; 

CGSize titleSize = [myAnnotation.THETEXT sizeWithFont:[UIFont systemFontOfSize:12]]; 
CGRect newFrame = self.frame; 
newFrame.size.height = titleSize.height + 12; 
newFrame.size.width = titleSize.width + 32; 
self.frame = newFrame; 
self.layer.borderColor = [UIColor colorWithRed:0 green:.3 blue:0 alpha:1.0f].CGColor; 
self.layer.borderWidth = 3.0; 

UILabel *infoLabel = [[UILabel alloc] initWithFrame:CGRectMake(26,5,newFrame.size.width-32,newFrame.size.height-12)]; 
infoLabel.text = myAnnotation.title; 
infoLabel.backgroundColor = [UIColor clearColor]; 
infoLabel.textColor = [UIColor blackColor]; 
infoLabel.textAlignment = UITextAlignmentCenter; 
infoLabel.font = [UIFont systemFontOfSize:12]; 

[self addSubview:infoLabel]; 
[infoLabel release]; 

En este ejemplo, estoy añadiendo un pin personalizado a una clase MKAnnotation maneja el tamaño de un UILabel de acuerdo con el tamano del texto. También agrega una imagen en el lado izquierdo de la vista, por lo que verá que parte del código administra el espaciado adecuado para manejar la imagen y el relleno.

La clave es usar CGSize titleSize = [myAnnotation.THETEXT sizeWithFont: [UIFont systemFontOfSize: 12]]; y luego redefinir las dimensiones de la vista. Puede aplicar esta lógica a cualquier vista, pero no controla los saltos de línea como los de Pajama.

Aunque la respuesta de Pajama funciona para algunos, no funcionó para mí. Esta es una explicación detallada que debe probar inmediatamente antes de ir a cualquier otro lugar si desea un pin MKAnnotation personalizado dinámico con una imagen y UILabel de tamaño variable.

Cuestiones relacionadas