¿Cómo envuelvo el texto en una UITableViewCell sin una celda personalizada?

151

Esto está en iPhone 0S 2.0. Las respuestas para 2.1 también están bien, aunque no conozco ninguna diferencia con respecto a las tablas.

Parece que debería ser posible hacer que el texto se ajuste sin crear una celda personalizada, ya que a UITableViewCellcontiene un UILabelvalor predeterminado. Sé que puedo hacer que funcione si creo una celda personalizada, pero eso no es lo que estoy tratando de lograr: quiero entender por qué mi enfoque actual no funciona.

He descubierto que la etiqueta se crea a pedido (ya que la celda admite el acceso de texto e imagen, por lo que no crea la vista de datos hasta que sea necesario), así que si hago algo como esto:

cell.text = @""; // create the label
UILabel* label = (UILabel*)[[cell.contentView subviews] objectAtIndex:0];

entonces obtengo una etiqueta válida, pero configurar numberOfLineseso (y lineBreakMode) no funciona, todavía recibo texto de una sola línea. Hay mucha altura en el UILabeltexto para mostrar; solo estoy devolviendo un valor grande para la altura heightForRowAtIndexPath.

Airsource Ltd
fuente

Respuestas:

277

Aquí hay una manera más simple, y funciona para mí:

Dentro de tu cellForRowAtIndexPath:función. La primera vez que crea su celda:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
    cell.textLabel.numberOfLines = 0;
    cell.textLabel.font = [UIFont fontWithName:@"Helvetica" size:17.0];
}

Notarás que configuré el número de líneas para la etiqueta en 0. Esto le permite usar tantas líneas como sea necesario.

La siguiente parte es especificar qué tan grande UITableViewCellserá, así que hazlo en tu heightForRowAtIndexPathfunción:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *cellText = @"Go get some text for your cell.";
    UIFont *cellFont = [UIFont fontWithName:@"Helvetica" size:17.0];
    CGSize constraintSize = CGSizeMake(280.0f, MAXFLOAT);
    CGSize labelSize = [cellText sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];

    return labelSize.height + 20;
}

Agregué 20 a la altura de mi celda devuelta porque me gusta un poco de búfer alrededor de mi texto.

Tim Rupe
fuente
17
No necesita establecer su cell.textLabel.numberOfLines en un número arbitrariamente alto. Establecerlo en 0 significa "tantas líneas como sea necesario para mostrar".
mmc
Gracias, editaré mi publicación esta noche después de que tenga la oportunidad de verificarla en mi propio proyecto.
Tim Rupe
1
Ajuste de número de líneas a 0 bien funciona (tantas líneas como sea necesario para pantalla)
Prakash
1
cagreen: Resulta que puedo replicar esto, pero solo si uso iPhone OS 3.0 en el simulador. Cuando uso 3.1+, el cambio de tamaño de detailTextLabel coincide con el de sizeWithFont. Por lo tanto, el método de Tim funciona realmente bien, solo para 3.1+ (probablemente debido a un error / mal funcionamiento en la representación de celda predeterminada 3.0). Para el registro, estoy usando un margen vertical superior / inferior de 12 (cada uno), un tamaño de etiqueta de texto de detalle de (188.0, CGFLOAT_MAX) y un boldSystemFontOfSize 15.
Joe D'Andrea
17
UILineBreakModeWordWrap está en desuso en iOS 6. Utilice NSLineBreakByWordWrapping en su lugar.
Ethan Allen
16

La respuesta de Tim Rupe actualizada para iOS7:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] ;
    cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping;
    cell.textLabel.numberOfLines = 0;
    cell.textLabel.font = [UIFont fontWithName:@"Helvetica" size:17.0];
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *cellText = @"Go get some text for your cell.";
    UIFont *cellFont = [UIFont fontWithName:@"Helvetica" size:17.0];

    NSAttributedString *attributedText =
        [[NSAttributedString alloc]
            initWithString:cellText
            attributes:@
            {
                NSFontAttributeName: cellFont
            }];
    CGRect rect = [attributedText boundingRectWithSize:CGSizeMake(tableView.bounds.size.width, CGFLOAT_MAX)
                                               options:NSStringDrawingUsesLineFragmentOrigin
                                               context:nil];
    return rect.size.height + 20;
}
ddiego
fuente
3

Un breve comentario / respuesta para registrar mi experiencia cuando tuve el mismo problema. A pesar de usar los ejemplos de código, la altura de la celda de la vista de tabla se estaba ajustando, pero la etiqueta dentro de la celda todavía no se ajustaba correctamente; la solución fue que estaba cargando mi celda desde un archivo NIB personalizado, lo que sucede después de que la altura de la celda se ajusta.

Y tenía mi configuración dentro del archivo NIB para no ajustar el texto, y solo tengo 1 línea para la etiqueta; la configuración del archivo NIB anulaba la configuración que ajusté dentro del código.

La lección que tomé fue asegurarme de tener siempre en cuenta cuál es el estado de los objetos en cada momento, ¡es posible que aún no se hayan creado! ... hth alguien en el futuro.

Richard Le Mesurier
fuente
2

Si vamos a agregar solo texto en la UITableViewcelda, solo necesitamos dos delegados para trabajar (no es necesario agregar más UILabels)

1) cellForRowAtIndexPath

2) heightForRowAtIndexPath

Esta solución funcionó para mí: -

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{ 
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil)
    {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    cell.textLabel.font = [UIFont fontWithName:@"Helvetica" size:16];
    cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
    cell.textLabel.numberOfLines = 0;

    [cell setSelectionStyle:UITableViewCellSelectionStyleGray]; 
    cell.textLabel.text = [mutArr objectAtIndex:indexPath.section];
    NSLog(@"%@",cell.textLabel.text);

    cell.accessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"arrow.png" ]];

    return cell;

}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{  
    CGSize labelSize = CGSizeMake(200.0, 20.0);

    NSString *strTemp = [mutArr objectAtIndex:indexPath.section];

    if ([strTemp length] > 0)
        labelSize = [strTemp sizeWithFont: [UIFont boldSystemFontOfSize: 14.0] constrainedToSize: CGSizeMake(labelSize.width, 1000) lineBreakMode: UILineBreakModeWordWrap];

    return (labelSize.height + 10);
}

Aquí la cadena mutArres una matriz mutable de la que obtengo mis datos.

EDITAR: - Aquí está la matriz que tomé.

mutArr= [[NSMutableArray alloc] init];

[mutArr addObject:@"HEMAN"];
[mutArr addObject:@"SUPERMAN"];
[mutArr addObject:@"Is SUPERMAN powerful than HEMAN"];
[mutArr addObject:@"Well, if HEMAN is weaker than SUPERMAN, both are friends and we will never get to know who is more powerful than whom because they will never have a fight among them"];
[mutArr addObject:@"Where are BATMAN and SPIDERMAN"];
Arshad Parwez
fuente
2

Ahora las vistas de tabla pueden tener celdas de tamaño propio. Configure la vista de tabla de la siguiente manera

tableView.estimatedRowHeight = 85.0 //use an appropriate estimate tableView.rowHeight = UITableViewAutomaticDimension

Referencia de Apple

Jason
fuente
0

Yo uso las siguientes soluciones.

Los datos se proporcionan por separado en un miembro:

-(NSString *)getHeaderData:(int)theSection {
    ...
    return rowText;
}

El manejo se puede hacer fácilmente cellForRowAtIndexPath. Defina la celda / defina la fuente y asigne estos valores al resultado "celda". Tenga en cuenta que numberoflinesse establece en "0", lo que significa tomar lo que se necesita.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    UIFont *cellFont = [UIFont fontWithName:@"Verdana" size:12.0];
    cell.textLabel.text= [self getRowData:indexPath.section];
    cell.textLabel.font = cellFont;
    cell.textLabel.numberOfLines=0;
    return cell;
}

En heightForRowAtIndexPath, calculo las alturas del texto envuelto. El tamaño del cuerpo estará relacionado con el ancho de su celda. Para iPad será 1024. Para iPhone en iPod 320.

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UIFont *cellFont = [UIFont fontWithName:@"Verdana" size:12.0];
    CGSize boundingSize = CGSizeMake(1024, CGFLOAT_MAX);
    CGSize requiredSize = [[self getRowData:indexPath.section] sizeWithFont:cellFont constrainedToSize:boundingSize lineBreakMode:UILineBreakModeWordWrap];
    return requiredSize.height;    
}
Vincent
fuente
0

Encontré que esto es bastante simple y directo:

[self.tableView setRowHeight:whatEvereight.0f];

por ejemplo:

[self.tableView setRowHeight:80.0f];

Este puede o no ser el mejor enfoque estándar para hacerlo, pero funcionó en mi caso.

Manish Kr. Shukla
fuente
Según tengo entendido, la propiedad rowHeight establece una altura fija que se utilizará para todas las celdas en la vista de tabla. El uso de rowHeight es mejor para el rendimiento en tablas grandes, pero si necesita que la altura de cada celda varíe en función de su contenido, entonces parece que se debe usar tableView: heightForRowAtIndexPath: método.
jk7
0

Prueba mi código rápidamente. Este código también funcionará para UILabels normales.

extension UILabel {
    func lblFunction() {
        //You can pass here all UILabel properties like Font, colour etc....
        numberOfLines = 0
        lineBreakMode = .byWordWrapping//If you want word wraping
        lineBreakMode = .byCharWrapping//If you want character wraping
    }
}

Ahora llama simplemente así

cell.textLabel.lblFunction()//Replace your label name 
iOS
fuente
-1

Creo que esta es una solución mejor y más corta. Simplemente formatee el UILabel( textLabel) de la celda para calcular automáticamente la altura especificando sizeToFity todo debería estar bien.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil)
    {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    // Configure the cell...
    cell.textLabel.text = @"Whatever text you want to put here is ok";
    cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
    cell.textLabel.numberOfLines = 0;
    [cell.textLabel sizeToFit];

    return cell;
}
dukz
fuente
-2

No creo que puedas manipular una base UITableViewCell'sprivada UILabelpara hacer esto. Se podría añadir un nuevo UILabela la celda de uno mismo y utilizar numberOfLinescon sizeToFitel tamaño de manera apropiada. Algo como:

UILabel* label = [[UILabel alloc] initWithFrame:cell.frame];
label.numberOfLines = <...an appriate number of lines...>
label.text = <...your text...>
[label sizeToFit];
[cell addSubview:label];
[label release];
Drew
fuente