No se puede cambiar el marco de una UILabel en una UITableViewCell cuando aparece por primera vez (utilizando Autolayout)

Tengo una celda prototipo dentro de mi UITableView que contiene un UILabel . Quiero cambiar dinámicamente el tamaño de la label (y la celda) según el tamaño del text en la label.

Creo la celda prototipo en cellForRowAtIndexPath así:

 static NSString *CellIdentifier = @"ProgramDetailCell"; ProgramDetailCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; cell.descriptionLabel.text = self.program.subtitle; return cell; 

Entonces mi ProgramDetailCell tiene la siguiente implementación:

 @implementation ProgramDetailCell - (void)layoutSubviews { [super layoutSubviews]; [self.descriptionLabel sizeToFit]; } @end 

La primera vez que se muestra la celda, se llama a layoutSubviews , pero la descriptionLabel no layoutSubviews tamaño. Sin embargo, si me desploop hacia abajo en la tabla y vuelvo a hacer una copy de security, aparece la celda "reutilizada" con la label correctamente networkingimensionada.

¿Por qué no funciona la primera vez que se muestra la celda? Y qué necesito hacer para solucionarlo.

¡Gracias por adelantado!

En xib, vaya a la primera pestaña, en el documento de Interface Builder, desactive la casilla Utilizar layout automático.

No funciona porque está utilizando el auto layout . Necesita una forma de auto layout para lograr esto.

Aquí está la solución.

Paso 1 :

Tenga el UILabel a la parte superior e inferior de UITableViewCell . Puede lograr esto a través del Interface Builder al tener Vertical Constraint en UILabel desde la top e bottom de la celda. Esto hará que UILabel aumente de altura si la altura de la celda aumenta o viceversa.

Paso 2:

En su UIViewController en - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath método - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath calcula el tamaño de UITableViewCell .

Puede calcularlo usando:

  CGRect textFrame = [YourText boundingRectWithSize:CGSizeMake(width of the label, FLT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:Your Font} context:nil]; 

ahora devuelve el relleno textFrame.size.height + si está presente.

Paso 3 :

Lograrás lo que querías — "cambia dinámicamente el tamaño de la label (y la celda) según el tamaño del text en la label" después de comstackr y ejecutar incluso por primera vez.

Después de recuperar todos los datos del server, puede get la altura de ese UILabel utilizando este método.

 CGSize maximumSize = CGSizeMake(210, 9999); for (int i = 0; i < [_arrProductList count]; i++) { float row_height = 0.0f; ProductInformation *product_obj = [_arrProductList objectAtIndex:i]; CGSize desc_size = [self measureHeightForText:product_obj.product_desc forFont: [UIFont systemFontOfSize:14] forSize:maximumSize]; row_height = row_height + desc_size.height; // [_arrRowHeights addObject:[NSString stringWithFormat:@"%f", row_height]]; You can take it into array. } [tableView reloadData]; 

Y aquí he dado una descripción de measureHeightForText: Esta lógica funciona en todos los iOS5 , iOS6 y iOS7 .

 -(CGSize)measureHeightForText:(NSString *)strText forFont:(UIFont *)font forSize:(CGSize)size{ if (!testingLabel) { testingLabel = [[UILabel alloc] init]; // testingLabel.font = [UIFont fontWithName:[AppHandlers zHandler].fontName size:16]; testingLabel.text = @""; testingLabel.numberOfLines = 0; } testingLabel.text =strText; testingLabel.font = font; CGSize expectedSize = [testingLabel sizeThatFits:size]; return expectedSize; } 

Y luego actualiza el tamaño de tu label según él. Esto está funcionando bien para mí. Lo estoy usando.

Porque cuando layoutSubviews se llama tu descriptionLabel , el text de layoutSubviews aún no está configurado. Y cuando se desplaza, el text está configurado. Entonces es correcto ahora.

Sugiero que llame a sizeToFit después de configurar el text.

 static NSString *CellIdentifier = @"ProgramDetailCell"; ProgramDetailCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; cell.descriptionLabel.text = self.program.subtitle; [cell.descriptionLabel sizeToFit]; return cell; 

Llame a esto en heightForRowAtIndexPath y calcule manualmente la altura

 static NSString *CellIdentifier = @"ProgramDetailCell"; ProgramDetailCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; cell.descriptionLabel.text = self.program.subtitle; [cell.descriptionLabel sizeToFit]; return cell.descriptionLabel.frame.size.height+cell.descriptionLabel.frame.origin.y; 

Puede usar el siguiente código:

 //Calculate the expected size based on the font and linebreak mode of your label // FLT_MAX here simply means no constraint in height CGSize maximumLabelSize = CGSizeMake(296, FLT_MAX); 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; 

Si su requisito cambia de forma dinámica la altura de la label, siga el siguiente enlace. Cuando necesitamos cambiar la altura de la label, también debemos cambiar la altura de la fila:

Cambiar el tamaño de UILabel no funciona del todo

Use el código a continuación para la altura dinámica configurada en celda

 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { NSString *messagetext=[NSString stringWithFormat:@"%@",[[arryStoryView objectAtIndex:indexPath.row] valueForKey:@"messagetext"]]; CGSize StoryTextSize= [messagetext sizeWithFont:[UIFont fontWithName:@"Georgia" size:17.0f] constrainedToSize:CGSizeMake(300, MAXFLOAT) lineBreakMode:NSLineBreakByWordWrapping]; int TotalHeight; TotalHeight= StoryTextSize.height + 10; return TotalHeight; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell1"; UITableViewCell *cell=[tblSendMsg dequeueReusableCellWithIdentifier:CellIdentifier]; cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; cell.selectionStyle = UITableViewCellSelectionStyleNone; NSString *storytext=[NSString stringWithFormat:@"%@",[[arryStoryView objectAtIndex:indexPath.row] valueForKey:@"storytext"]]; CGSize StoryTextSize = [storytext sizeWithFont:[UIFont fontWithName:@"Georgia" size:17.0f] constrainedToSize:CGSizeMake(300, MAXFLOAT) lineBreakMode:NSLineBreakByWordWrapping]; lblStoryText.frame=CGRectMake(5, 25, [[UIScreen mainScreen] bounds].size.width-10, StoryTextSize.height+30); int nooflines=StoryTextSize.height/16; int i= StoryTextSize.height; if(i%16 !=0) { nooflines=nooflines+1; } lblStoryText.numberOfLines=nooflines; lblStoryText.font=[UIFont fontWithName:@"Georgia" size:17.0f]; lblStoryText.text=[NSString stringWithFormat:@"%@",storytext]; return cell; } 

Si está utilizando la reproducción automática, la modificación del marco no tendrá efecto.

En su lugar, debe modificar las restricciones.