Configuración de altura personalizada de UITableViewCells

votos
209

Estoy usando una UITableViewCell personalizada que tiene algunas etiquetas, botones y vistas de imágenes para mostrar. Hay una etiqueta en la celda cuyo texto es un NSStringobjeto y la longitud de la cadena podría ser variable. Debido a esto, no puedo establecer una altura constante a la célula en el UITableView's heightForCellAtIndexmétodo. La altura de la célula depende de la altura de la etiqueta que se puede determinar utilizando el NSString's sizeWithFontmétodo. Intenté usarlo, pero parece que me estoy equivocando en alguna parte. ¿Cómo se puede arreglar?

Aquí está el código usado para inicializar la celda.

if (self = [super initWithFrame:frame reuseIdentifier:reuseIdentifier])
{
    self.selectionStyle = UITableViewCellSelectionStyleNone;
    UIImage *image = [UIImage imageNamed:@dot.png];
    imageView = [[UIImageView alloc] initWithImage:image];
    imageView.frame = CGRectMake(45.0,10.0,10,10);

    headingTxt = [[UILabel alloc] initWithFrame:   CGRectMake(60.0,0.0,150.0,post_hdg_ht)];
    [headingTxt setContentMode: UIViewContentModeCenter];
    headingTxt.text = postData.user_f_name;
    headingTxt.font = [UIFont boldSystemFontOfSize:13];
    headingTxt.textAlignment = UITextAlignmentLeft;
    headingTxt.textColor = [UIColor blackColor];

    dateTxt = [[UILabel alloc] initWithFrame:CGRectMake(55.0,23.0,150.0,post_date_ht)];
    dateTxt.text = postData.created_dtm;
    dateTxt.font = [UIFont italicSystemFontOfSize:11];
    dateTxt.textAlignment = UITextAlignmentLeft;
    dateTxt.textColor = [UIColor grayColor];

    NSString * text1 = postData.post_body;
    NSLog(@text length = %d,[text1 length]);
    CGRect bounds = [UIScreen mainScreen].bounds;
    CGFloat tableViewWidth;
    CGFloat width = 0;
    tableViewWidth = bounds.size.width/2;
    width = tableViewWidth - 40; //fudge factor
    //CGSize textSize = {width, 20000.0f}; //width and height of text area
    CGSize textSize = {245.0, 20000.0f}; //width and height of text area
    CGSize size1 = [text1 sizeWithFont:[UIFont systemFontOfSize:11.0f]
                        constrainedToSize:textSize lineBreakMode:UILineBreakModeWordWrap];

    CGFloat ht = MAX(size1.height, 28);
    textView = [[UILabel alloc] initWithFrame:CGRectMake(55.0,42.0,245.0,ht)];
    textView.text = postData.post_body;
    textView.font = [UIFont systemFontOfSize:11];
    textView.textAlignment = UITextAlignmentLeft;
    textView.textColor = [UIColor blackColor];
    textView.lineBreakMode = UILineBreakModeWordWrap;
    textView.numberOfLines = 3;
    textView.autoresizesSubviews = YES;

    [self.contentView addSubview:imageView];
    [self.contentView addSubview:textView];
    [self.contentView addSubview:webView];
    [self.contentView addSubview:dateTxt];
    [self.contentView addSubview:headingTxt];
    [self.contentView sizeToFit];

    [imageView release];
    [textView release];
    [webView release];
    [dateTxt release];
    [headingTxt release];
}

Esta es la etiqueta cuya altura y ancho van mal:

textView = [[UILabel alloc] initWithFrame:CGRectMake(55.0,42.0,245.0,ht)];
Publicado el 30/01/2009 a las 06:27
fuente por usuario
En otros idiomas...                            


9 respuestas

votos
483

Tu UITableViewDelegatedeberías implementartableView:heightForRowAtIndexPath:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return [indexPath row] * 20;
}

Probablemente quieras usar NSStringel sizeWithFont:constrainedToSize:lineBreakMode:método de 's para calcular la altura de tus filas en lugar de solo realizar algunas matemáticas tontas en el indexPath :)

Respondida el 30/01/2009 a las 23:46
fuente por usuario

votos
121

Si todos sus filas tienen la misma altura, acaba de establecer la rowHeightpropiedad del UITableView en lugar de aplicar el heightForRowAtIndexPath. Documentos de Apple:

Existen implicaciones de rendimiento en el uso de tableView: heightForRowAtIndexPath: en lugar de rowHeight. Cada vez que se muestra una vista de tabla, que llama tableView: heightForRowAtIndexPath: por el delegado de cada una de sus filas, lo cual puede resultar en un problema significativo rendimiento con vistas de tabla con un gran número de filas (aproximadamente 1000 o más).

Respondida el 19/01/2011 a las 00:59
fuente por usuario

votos
22

en una costumbre UITableViewCell -controller añadir este

-(void)layoutSubviews {  

    CGRect newCellSubViewsFrame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
    CGRect newCellViewFrame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, self.frame.size.height);

    self.contentView.frame = self.contentView.bounds = self.backgroundView.frame = self.accessoryView.frame = newCellSubViewsFrame;
    self.frame = newCellViewFrame;

    [super layoutSubviews];
}

En el UITableView -controller agregar este

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return [indexPath row] * 1.5; // your dynamic height...
}
Respondida el 19/01/2010 a las 14:26
fuente por usuario

votos
17
#define FONT_SIZE 14.0f
#define CELL_CONTENT_WIDTH 300.0f
#define CELL_CONTENT_MARGIN 10.0f

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath      *)indexPath;
{
   /// Here you can set also height according to your section and row
   if(indexPath.section==0 && indexPath.row==0)
   {
     text=@"pass here your dynamic data";

     CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);

     CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE]      constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];

     CGFloat height = MAX(size.height, 44.0f);

     return height + (CELL_CONTENT_MARGIN * 2);
   }
   else
   {
      return 44;
   }
}

- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell;
    UILabel *label = nil;

    cell = [tv dequeueReusableCellWithIdentifier:@"Cell"];
    if (cell == nil)
    {
       cell = [[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:@"Cell"];
    }
    ********Here you can set also height according to your section and row*********
    if(indexPath.section==0 && indexPath.row==0)
    {
        label = [[UILabel alloc] initWithFrame:CGRectZero];
        [label setLineBreakMode:UILineBreakModeWordWrap];
        [label setMinimumFontSize:FONT_SIZE];
        [label setNumberOfLines:0];
        label.backgroundColor=[UIColor clearColor];
        [label setFont:[UIFont systemFontOfSize:FONT_SIZE]];
        [label setTag:1];

        // NSString *text1 =[NSString stringWithFormat:@"%@",text];

        CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);

        CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];

        if (!label)
        label = (UILabel*)[cell viewWithTag:1];


        label.text=[NSString stringWithFormat:@"%@",text];
        [label setFrame:CGRectMake(CELL_CONTENT_MARGIN, CELL_CONTENT_MARGIN, CELL_CONTENT_WIDTH          - (CELL_CONTENT_MARGIN * 2), MAX(size.height, 44.0f))];
        [cell.contentView addSubview:label];
    }
return cell;
}
Respondida el 19/09/2012 a las 10:30
fuente por usuario

votos
8
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{
    CGSize constraintSize = {245.0, 20000}
    CGSize neededSize = [ yourText sizeWithFont:[UIfont systemFontOfSize:14.0f] constrainedToSize:constraintSize  lineBreakMode:UILineBreakModeCharacterWrap]
if ( neededSize.height <= 18) 

   return 45
else return neededSize.height + 45 
//18 is the size of your text with the requested font (systemFontOfSize 14). if you change fonts you have a different number to use  
// 45 is what is required to have a nice cell as the neededSize.height is the "text"'s height only
//not the cell.

}
Respondida el 18/11/2012 a las 17:20
fuente por usuario

votos
5

Vi un montón de soluciones pero todo estaba equivocado o uncomplet. Usted puede resolver todos los problemas con 5 líneas en viewDidLoad y el diseño automático. Esto para C Objetivo:

_tableView.delegate = self;
_tableView.dataSource = self;
self.tableView.estimatedRowHeight = 80;//the estimatedRowHeight but if is more this autoincremented with autolayout
self.tableView.rowHeight = UITableViewAutomaticDimension;
[self.tableView setNeedsLayout];
[self.tableView layoutIfNeeded];
self.tableView.contentInset = UIEdgeInsetsMake(20, 0, 0, 0) ;

Para SWIFT 2.0:

 self.tableView.estimatedRowHeight = 80
 self.tableView.rowHeight = UITableViewAutomaticDimension      
 self.tableView.setNeedsLayout()
 self.tableView.layoutIfNeeded()
 self.tableView.contentInset = UIEdgeInsetsMake(20, 0, 0, 0)

Ahora crear su celda con xib o en tableview en su Storyboard Con esto no hay necesidad de implementar ni más ni anular. (Don olvida el número de líneas os 0) y la etiqueta inferior (limitar) rebajar "abraza el contenido Prioridad - vertical a 250"

introducir descripción de la imagen aquí introducir descripción de la imagen aquí

Puede donwload el código en la siguiente URL: https://github.com/jposes22/exampleTableCellCustomHeight

Referencias: http://candycode.io/automatically-resizing-uitableviewcells-with-dynamic-text-height-using-auto-layout/

Respondida el 26/01/2016 a las 16:58
fuente por usuario

votos
5

Gracias a todos los mensajes sobre este tema, hay algunas maneras muy útiles para ajustar el rowHeight de un UITableViewCell.

Aquí es una recopilación de algunos de los conceptos de todos los demás que realmente ayuda a la hora de construir para el iPhone y el IPAD. También puede acceder a diferentes secciones y ajustarlos de acuerdo a los diferentes tamaños de puntos de vista.

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
    int cellHeight = 0;

    if ([indexPath section] == 0) 
    {
        cellHeight = 16;
        settingsTable.rowHeight = cellHeight;
    }
    else if ([indexPath section] == 1)
    {
        cellHeight = 20;
        settingsTable.rowHeight = cellHeight;
    }

    return cellHeight;
}
else
{
    int cellHeight = 0;

    if ([indexPath section] == 0) 
    {
        cellHeight = 24;
        settingsTable.rowHeight = cellHeight;
    }
    else if ([indexPath section] == 1)
    {
        cellHeight = 40;
        settingsTable.rowHeight = cellHeight;
    }

    return cellHeight;
}
return 0;
} 
Respondida el 22/03/2012 a las 21:02
fuente por usuario

votos
3

Para tener la altura de la celda dinámico como el texto de los aumentos de la etiqueta, primero tiene que calcular la altura, que el texto va a usar en -heightForRowAtIndexPathel método delegado y regresar con las alturas añadidos de otros lables, imágenes (altura máxima de texto + altura de otra estática componenets) y utilizar la misma altura en la creación de células.

#define FONT_SIZE 14.0f
#define CELL_CONTENT_WIDTH 300.0f  
#define CELL_CONTENT_MARGIN 10.0f

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{

    if (indexPath.row == 2) {  // the cell you want to be dynamic

        NSString *text = dynamic text for your label;

        CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);
        CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];

        CGFloat height = MAX(size.height, 44.0f);

        return height + (CELL_CONTENT_MARGIN * 2);
    }
    else {
        return 44; // return normal cell height
    }
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    UILabel *label;

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

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

    label = [[UILabel alloc] initWithFrame:CGRectMake(10, 5, 280, 34)];

    [label setNumberOfLines:2];

    label.backgroundColor = [UIColor clearColor];

    [label setFont:[UIFont systemFontOfSize:FONT_SIZE]];

    label.adjustsFontSizeToFitWidth = NO;

    [[cell contentView] addSubview:label];


    NSString *text = dynamic text fro your label;

    [label setText:text];

    if (indexPath.row == 2) {// the cell which needs to be dynamic 

        [label setNumberOfLines:0];

        CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);

        CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];

        [label setFrame:CGRectMake(CELL_CONTENT_MARGIN, CELL_CONTENT_MARGIN, CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), MAX(size.height, 44.0f))];

    }
    return  cell;
}
Respondida el 01/08/2012 a las 12:07
fuente por usuario

votos
2

Para establecer la dimensión automático de altura de la fila y altura estimada fila, garantizar siguientes pasos para hacer efectiva, dimensión de auto para la disposición altura de la celda / fila.

  • Asignar y aplicar dataSource tableview y delegar
  • Asignar UITableViewAutomaticDimensiona rowHeight y estimatedRowHeight
  • Implementar delegado / métodos dataSource (es decir, heightForRowAty devolver un valor UITableViewAutomaticDimensiona ella)

-

C objetivo:

// in ViewController.h
#import <UIKit/UIKit.h>

@interface ViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>

  @property IBOutlet UITableView * table;

@end

// in ViewController.m

- (void)viewDidLoad {
    [super viewDidLoad];
    self.table.dataSource = self;
    self.table.delegate = self;

    self.table.rowHeight = UITableViewAutomaticDimension;
    self.table.estimatedRowHeight = UITableViewAutomaticDimension;
}

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {

    return UITableViewAutomaticDimension;
}

Rápido:

@IBOutlet weak var table: UITableView!

override func viewDidLoad() {
    super.viewDidLoad()

    // Don't forget to set dataSource and delegate for table
    table.dataSource = self
    table.delegate = self

    // Set automatic dimensions for row height
    table.rowHeight = UITableViewAutomaticDimension
    table.estimatedRowHeight = UITableViewAutomaticDimension
}



// UITableViewAutomaticDimension calculates height of label contents/text
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

Por ejemplo etiqueta en UITableViewCell

  • Establecer el número de líneas = 0 (y del modo de salto de línea = truncar la cola)
  • Establecer todas las restricciones (superior, inferior, derecho e izquierdo) con respecto a su contenedor supervista / célula.
  • Opcional : Establecer la altura mínima de la etiqueta, si quieres área vertical mínima cubierta por la etiqueta, incluso si no hay datos.

introducir descripción de la imagen aquí

Nota : Si usted tiene más de un etiquetas (UiElements) con una longitud dinámico, que debe ser ajustado de acuerdo a su tamaño contenido: Ajuste 'que abraza el contenido y la resistencia a la compresión Priority` para las etiquetas que desea expandir / comprimir con mayor prioridad.

Aquí, en este ejemplo puse bajo abrazos y prioridad alta resistencia a la compresión, que conduce a establecer más prioridad / importancia para los contenidos de segunda etiqueta (amarillo).

introducir descripción de la imagen aquí

Respondida el 02/02/2018 a las 12:20
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more