ios ios7 uilabel nstextattachment textkit

ios - Líneas que faltan desde la altura de UILabel al incrustar NSTextAttachment



ios7 textkit (4)

¿Intentó obtener la altura real del texto usando el método boundingRectWithSize:

NSAttributedString *text; CGFloat width = 200; CGRect rect = [text boundingRectWithSize:CGSizeMake(width, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading context:nil]; CGFloat height = rect.size.height;

Puedo crear una NSAttributedString utilizando caracteres de nueva línea escapados ( @"/n" ). Con iOS 7, ahora puedo incrustar un UIImage dentro de cadenas atribuidas (a través de NSTextAttachment ).

Me he dado cuenta de que cada vez que configuro el UILabel de un UILabel en una cadena multilínea con una imagen incrustada, la cantidad de líneas que se muestran en realidad es inversamente proporcional a la altura de la etiqueta. Por ejemplo, cuando la altura de la etiqueta es 80, aparecen dos líneas; cuando la altura es de alrededor de 100, solo aparece la segunda línea; cuando la altura es de unos 130, nada aparece.

Este problema se produjo al intentar colocar varios UILabels de lado a lado dentro de un UITableViewCell y hacer que las etiquetas crezcan (verticalmente) con la altura de la celda.

¿Puede alguien explicar por qué ocurre esto? ¿Alguien sabe soluciones que no impliquen hacer la UILabel más pequeña?

Código de muestra:

@implementation SOViewController - (void)viewDidLoad { [super viewDidLoad]; NSMutableAttributedString *text1 = [[NSMutableAttributedString alloc] init]; [text1 appendAttributedString:[[NSAttributedString alloc] initWithString:@"Line 1/n"]]; [text1 appendAttributedString:[[NSAttributedString alloc] initWithString:@"Line 2"]]; UIImage *image = [UIImage imageNamed:@"17x10"]; //some PNG image (17px by 10px) NSTextAttachment *attachment = [[NSTextAttachment alloc] init]; attachment.image = image; attachment.bounds = CGRectMake(0, 0, image.size.width, image.size.height); NSMutableAttributedString *text2 = [[NSMutableAttributedString alloc] init]; [text2 appendAttributedString:[[NSAttributedString alloc] initWithString:@"Line 1/n"]]; [text2 appendAttributedString:[NSAttributedString attributedStringWithAttachment:attachment]]; [text2 appendAttributedString:[[NSAttributedString alloc] initWithString:@"Line 2"]]; CGFloat margin = 20; //shows both lines when height == 80 //shows line 2 when 90 <= height <= 120 //shows nothing when height == 130 CGFloat height = ???; CGFloat width = 200; UILabel *label1 = [[UILabel alloc] initWithFrame:CGRectMake(margin, margin, width, height)]; UILabel *label2 = [[UILabel alloc] initWithFrame:CGRectMake(margin, margin + height, width, height)]; [self.view addSubview:label1]; [self.view addSubview:label2]; label1.backgroundColor = [UIColor orangeColor]; label2.backgroundColor = [UIColor blueColor]; label2.textColor = [UIColor whiteColor]; label1.numberOfLines = 0; label2.numberOfLines = 0; label1.attributedText = text1; label2.attributedText = text2; UIImageView *imageView = [[UIImageView alloc] initWithImage:image]; imageView.frame = CGRectMake(margin + width, margin + height, image.size.width, image.size.height); [self.view addSubview:imageView]; } @end

... Ponga esto en el controlador de vista predeterminado de una "Aplicación de vista única". (Puedes elegir tu propia imagen).


He encontrado otra solución alternativa para este error, que es lo suficientemente diferente de mi respuesta anterior, que lo ofrezco como otra respuesta: deje que la etiqueta establezca su propia altura.

En este código, estoy eliminando la restricción de altura de una etiqueta con una restricción de ancho fijo y reemplazándola con una restricción de mayor que la altura (y estoy seguro de que hay otras formas de lograr el mismo resultado):

[self.lab removeConstraint:self.labelHeight]; [self.lab addConstraint: [NSLayoutConstraint constraintWithItem:self.lab attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:0 multiplier:1 constant:20]];

¡Esa etiqueta muestra correctamente cada cadena atribuida que le lanzo! Por supuesto, pierdes el centrado vertical automático de la cadena, pero esa es toda la fuente del error, por lo que perderla no es tan terrible.


Parece ser un error en UILabel . El mismo código funciona bien cuando se usa UITextView lugar de UILabel (el tamaño de fuente predeterminado de UITextView es diferente, así que lo probé en diferentes alturas).


Realmente no tiene nada que ver con el NSTextAttachment. Es que en iOS 7 como se lanzó hasta ahora, UILabel no es muy buena dibujando cadenas atribuidas. Una cadena atribuida simple con algo de subrayado y un estilo de párrafo centrado se mostrará en blanco, o parcialmente en blanco, en un UILabel; la misma cadena atribuida dibuja bien en un UITextView.

Entonces, una solución por ahora es: Use UITextView en su lugar. Esta es realmente una solución bastante buena porque, en iOS 7, UITextView es solo una envoltura alrededor de la pila del Kit de texto. Así que está dibujando la cadena atribuida de una manera directa. No se ve obstaculizada por la relación bajo el capó con Web Kit que tenía en versiones anteriores de iOS.

Por otro lado, también he encontrado una solución para este error de UILabel; tiene que jugar con el número de líneas de la etiqueta y la cadena de forma que el texto quede atascado en la parte superior de la etiqueta: vea mi respuesta aquí: https://.com/a/19409962/341994

O simplemente puede esperar a que Apple corrija el error y mantenga los dedos cruzados. EDITAR: En iOS 7.1, parece que el error se solucionará y no se necesitará ninguna solución.