He visto esta pregunta muchas veces, pero sorprendentemente, no he visto una respuesta coherente, así que voy a darle una oportunidad a mí mismo:

Si usted tiene un formato tableview que contiene su propio personalizado UITableViewCells que contienen UITextViews y UILabels cuya altura debe ser determinado en tiempo de ejecución, cómo se supone para determinar la altura de cada fila en heightForRowAtIndexPath?

El más obvio de la primera idea es calcular la altura de cada celda mediante el cálculo y, a continuación, suma de las alturas de cada punto de vista en el interior de la celda dentro de cellForRowAtIndexPath, y almacenar el final de altura total para su posterior recuperación.

Esto no funcionará sin embargo, debido a cellForRowAtIndexPath se llama DESPUÉS de que heightForRowAtIndexPath.

La única cosa que puedo pensar es en hacer todos los cálculos en el interior de viewDidLoad, crear todos los UITableViewCells entonces, calcular las células de la altura y de la tienda que en un campo personalizado en el interior de su UITableViewCell subclase, y poner a cada celda en un NSMutableDictionary con el indexPath como el de la clave y, a continuación, simplemente recuperar el celular desde el diccionario de uso de la indexPath dentro de cellForRowAtIndexPath y heightForRowAtIndexPath, devolviendo la costumbre valor de la altura o de la célula objeto en sí mismo.

Este enfoque parece mal, porque aunque no hace uso de dequeueReusableCellWithIdentifier, en lugar de eso sería la carga de todas las celdas a la vez en un diccionario en mi controlador, y el delegado de los métodos sería no hacer nada más que recuperar el correcto células del diccionario.

No veo ninguna otra manera de hacerlo, aunque. Esta es una mala idea – si es así, ¿cuál es la manera correcta de hacerlo?

  • La única cosa en común entre los dos métodos de delegado pasa a ser que NSIndexPath argumento, parece que tendrás que calcular basa solo en eso. Tal vez asignar sus puntos de vista en heightForRowAtIndexPath:, a continuación, colocarlos en cellForRowAtIndexPath:?
  • Bien que suena algo así como lo que he descrito haciendo, aunque pensaba que ya me gustaría ser la creación de todas las celdas a la vez que se debe hacer en viewDidLoad para asegurarse de que sólo se hace una vez.
  • Estoy teniendo el mismo problema. Es raro, porque esto parece un gran descuido en la API. Pero va en la suposición de que la Manzana de la API a los desarrolladores son mucho más inteligente que yo, me pregunto cuál es la forma correcta de hacerlo es?
  • La razón de que las dos cosas son independientes es que no se puede hacer scroll de la lista sin saber la altura de cada elemento (en concreto, de dibujo de la barra de desplazamiento es imposible), pero para largas listas de creación de cada una de las células es prohibitivamente caro.
InformationsquelleAutor JohnRock | 2011-01-27

10 Comentarios

  1. 60

    La forma en que Apple implementa UITableView no es intuitiva para todo el mundo, y es fácil entender el papel de heightForRowAtIndexPath:. La intención general es que este es más rápido y luz-en-método de la memoria que puede ser llamado por cada fila en la tabla con bastante frecuencia. Esto contrasta con cellForRowAtIndexPath: que es a menudo más lento y más intensivo de memoria, pero sólo para las filas que se necesita realmente para ser mostrado en cualquier momento dado.

    ¿Por qué Apple implementar algo como esto? Parte de la razón por la es que es casi siempre más barato (o puede ser más barato si el código es correcto) para calcular la altura de una fila de lo que es construir y llenar un conjunto de células. Dado que en muchas mesas a la altura de cada celda será idéntico, es a menudo considerablemente más barato. Y otra parte de la razón por la es debido a que iOS necesita saber el tamaño de toda la tabla: esto permite crear las barras de desplazamiento y establecer en un desplazamiento de la vista, etc.

    Así que, a menos que cada una de las células de la altura es la misma, entonces cuando un UITableView es creado y cada vez que envíe un reloadData mensaje, el origen de datos se envía una heightForRowAtIndexPath mensaje para cada celda. Así que si tu tabla tiene 30 células, el mensaje se envía a 30 veces. Dicen que sólo seis de los 30 células son visibles en la pantalla. En ese caso, cuando se crean y cuando se envía un reloadData mensaje, el UITableView enviará a uno cellForRowAtIndexPath mensaje por fila visible, es decir, que el mensaje se ha enviado seis veces.

    Algunas personas son a veces perplejo acerca de cómo calcular la altura de las células sin la creación de los puntos de vista propios. Pero generalmente esto es fácil de hacer.

    Por ejemplo, si la fila alturas varían en tamaño porque son los que tienen cantidades variables de texto, puede utilizar uno de los sizeWithFont: métodos en la cadena para hacer los cálculos. Esto es más rápido que la construcción de una vista y, a continuación, medir el resultado. Tenga en cuenta que si se cambia la altura de una celda, tendrá que volver a cargar toda la tabla (con reloadData – esto va a solicitar al delegado para cada una de las alturas, pero pedir sólo celdas visibles) O de forma selectiva recargar las filas en las que el tamaño ha cambiado (que, la última vez que revisé, también llamadas heightForRowAtIndexPath: en cada fila pero también hace un poco de desplazamiento de trabajo para una buena medida).

    Ver esta pregunta y quizás también este.

    • Creo que tu respuesta de verdad llega al corazón de la cuestión por responder ¿por qué heightForRowAtIndexPath se llama antes de que cellForRowAtIndexPath. Gran respuesta!
    • Hay, sin embargo, una captura, aunque: por lo general, usted tendrá que saber lo «ancho» tienes que darle a ‘- sizeWithFont:constrainedToSize:lineBreakMode:’ con el fin de calcular la altura correcta para una etiqueta contenida en la celda, por lo tanto la altura de la propia célula. Por desgracia, en el momento en que es llamado en la vista de tabla delegado ‘- formato tableview:heightForRowAtIndexPath:’ usted no tiene marcos o límites de las etiquetas de los contenidos en el interior de las células, por lo que tienen que «adivinar» de ellos. Esto se pone especialmente complicado si tienes apoyar tanto a iPhone, iPad en cualquier orientación, con tipos mixtos (por ejemplo, disclosured, o no, etc.)
    • Absolutamente, usted necesitará saber el ancho de si el uso de sizeWithFont:constrainedToSize:lineBreakMode: para hacer la medición. En una de mis aplicaciones, me parece que estoy probando para una amplia gama de casos (iPhone vs iPad + paisaje vs vertical + / edición no-edición). Puede haber formas más inteligentes de hacer que la palanca más potencia desde el sistema operativo. Y porque yo estoy haciendo todas las pruebas en bastante forma manual, tengo que actualizar para la Retina de 4, ya que requiere de diferentes anchos en el paisaje.
    • Esta es la mejor explicación que he visto de Apple UITableView aplicación en lo que respecta a la altura de las células.
    • Si su formato tableview tiene un ancho variable, puede diseñar la clase de método de cálculo de la altura de las células que acepta un «ancho» de los parámetros. (y de otros parámetros que usted necesita para calcular la altura de la celda en tiempo de ejecución)
    • Oblicuamente – que no sólo no ayudan si sus células contienen, dicen, las imágenes desde un servidor. (Y lo que las células no contienen imágenes desde un servidor? más que un «hola células!» tect!) Así, es absolutamente básico de descarga (digamos) la costumbre unos cientos de células de un servidor, y que contienen imágenes (y el texto) y las imágenes completamente variar en tamaño y forma. (así como el problema trivial del texto, que varían en tamaño y forma, por no hablar de la tipografía, el tamaño de fuente, etc.) En el examp, ¿cómo diablos sacas adelantado información sobre la altura de otros que en realidad la construcción de las células?!
    • Así un montón de células que contienen otras cosas, que las imágenes que se trajo desde el servidor. Ciertamente tengo que caso de uso. Pero incluso en el caso de uso que se centran en, si el servidor puede proporcionar el tamaño de la imagen de la información es probable que sea mucho más rápido / más eficaz utilizar para calcular el tamaño en lugar de construir una celda. En virtud de iOS7, también podría ser vale la pena mirar ‘estimatedRowHeight’ para ver si se puede mejorar el rendimiento. (No he hasta ahora se veía en la que yo mismo).

  2. 10

    Así, me pensar usted puede hacer esto sin tener que crear tus células, todos a la vez (que, como usted sugiere, es un desperdicio y también, probablemente, poco práctico para un gran número de células).

    UIKit añade un par de métodos para NSString, se puede haber olvidado de ellos, ya que no forman parte de los principales NSString documentación. Los de interés para empezar:

    - (CGSize)sizeWithFont...

    Aquí está el enlace a la Manzana docs.

    En teoría, estos NSString adiciones existe para este problema exacto: para averiguar el tamaño de un bloque de texto tomará sin necesidad de cargar la propia vista. Que presumiblemente ya tienen acceso al texto de cada celda como parte de su tabla de la vista de origen de datos.

    Digo «en teoría» porque si estás haciendo formato en su UITextView su kilometraje puede variar con esta solución. Pero tengo la esperanza de que usted consiga al menos una parte del camino. Hay un ejemplo de esto en El cacao es Mi Novia.

    • Dos cosas sobre lo que comentas: 1. Cuando me calcular la altura de un UITextView he encontrado la solución más fiable para hacer esto de esta manera:CGRect frame = questionCell.título.marco, marco.tamaño.altura = questionCell.título.contentSize.altura; auto.questionCell.título.frame = marco; 2. Sin embargo, eso no solucionar mi problema porque no es más que una UItextView o UILabel en el interior de la célula, así que usted tiene que calcular la altura de todos los elementos de la célula – y el punto es que no quiero estar haciendo que en más de un lugar, obviamente.
    • De hecho, me acabo de encontrar un post donde alguien sugiere hacer lo mismo menciono – la carga de todas las células en viewDidLoad: stackoverflow.com/questions/3228128/…
    • El NSString adiciones son la forma en la que usted averiguar cómo de alta una celda final será. Pero es necesario tener todo el contexto de la celda – la altura antes y después cambia el tamaño de la etiqueta – para ser capaz de determinar el total de la célula de altura para volver. Por lo tanto, mi idea antes de un prototipo de celda donde se pueden conseguir esas otras métricas de…
  3. 5

    Un enfoque que he utilizado en el pasado para crear una variable de clase para celebrar una sola instancia de la celda que se va a usar en la mesa (yo lo llamo un prototipo de celda). Luego en la celda personalizada clase tengo un método para rellenar los datos y determinar la altura de la celda debe ser. Tenga en cuenta que puede ser una variante más simple del método realmente rellenar los datos – en vez de realmente cambiar el tamaño de un UILabel en una celda, por ejemplo, puede utilizar el NSString la altura de los métodos para determinar la altura de la UILabel sería en la final de la celda y, a continuación, utilizar el total de la célula de altura (más de un borde en la parte inferior) y UILabel de colocación para determinar la altura real. Utiliza el prototipo de celular sólo para tener una idea de donde los elementos se colocan de modo que usted sabe lo que significa cuando una etiqueta que va a ser de 44 unidades de alto.

    En heightForRow: yo, a continuación, llamar a ese método para devolver la altura.

    En cellForRow: yo uso el método que realmente rellena las etiquetas y las redimensiona (nunca cambiar el tamaño de la UITableView celda).

    Si quieres obtener de fantasía, también puede almacenar en caché la altura para cada celda en función de los datos de paso (por ejemplo, que podría ser en un NSString si eso es todo lo que determina la altura). Si usted tiene una gran cantidad de datos que a menudo es el mismo podría tener sentido permanente de un caché en lugar de sólo en la memoria.

    También puede probar la estimación de número de línea basada en el carácter o número de palabras, pero mi experiencia es que nunca funciona – y cuando va mal lo general se mete una celda y todas las celdas de abajo.

    • Gracias! gran enfoque
  4. 5

    Esto es cómo puedo calcular la altura de una celda basada en la cantidad de texto en un UTextView:

    #define PADDING  21.0f
    
    - (CGFloat)tableView:(UITableView *)t heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    
        if(indexPath.section == 0 && indexPath.row == 0)
        {   
            NSString *practiceText = [practiceItem objectForKey:@"Practice"];
            CGSize practiceSize = [practiceText sizeWithFont:[UIFont systemFontOfSize:14.0f] 
                       constrainedToSize:CGSizeMake(tblPractice.frame.size.width - PADDING * 3, 1000.0f)];
            return practiceSize.height + PADDING * 3;
        }
    
        return 72;
    }

    Por supuesto, usted necesita para ajustar el PADDING y otras variables para adaptarse a sus necesidades, pero esto establece la altura de la celda que tiene un UITextView en él, basándose en la cantidad de texto proporcionado. así que si sólo hay 3 líneas de texto, el celular es bastante corto, mientras que si hay 14 líneas de texto, el celular es bastante grande en altura.

  5. 3

    La mejor aplicación de la presente que he visto es la forma en que el Three20 TTTableView clases de hacerlo.

    Básicamente no tienen una clase derivada de UITableViewController que los delegados de la heightForRowAtIndexPath: método a un método de clase en un TTTableCell clase.

    Que la clase, a continuación, devuelve la altura adecuada, siempre haciendo el mismo tipo de diseño de los cálculos como en el sorteo de los métodos. Con un movimiento de la clase, se evita la escritura de código que depende de la celda instancia.

    Realmente, no hay otra opción – por motivos de rendimiento, el marco no crear células antes de pedir a sus alturas, y que realmente no quieres hacer eso, si no que podría ser un montón de filas.

  6. 3

    El problema con el movimiento de la estimación de cada celda en formato tableview:heightForRowAtIndexPath: es que todas las células se vuelve a calcular cada vez que reloadData se llama. Demasiado lento, al menos para mi aplicación que puede ser de 100 filas. He aquí una solución alternativa que utiliza un defecto de la altura de la fila, y se almacena en caché el alto de la fila cuando se calculan. Cuando una altura de cambios, o se calculó por primera vez, una tabla de recarga está programada para informar a la vista de la tabla de las nuevas alturas. Esto significa que las filas se muestran dos veces cuando sus alturas cambio, pero que es menor en comparación:

    @interface MyTableViewController : UITableViewController {
        NSMutableDictionary *heightForRowCache;
        BOOL reloadRequested;
        NSInteger maxElementBottom;
        NSInteger minElementTop;
    }

    formato tableview:heightForRowAtIndexPath:

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        //If we've calculated the height for this cell before, get it from the height cache.  If
        //not, return a default height.  The actual size will be calculated by cellForRowAtIndexPath
        //when it is called.  Do not set too low a default or UITableViewController will request
        //too many cells (with cellForRowAtIndexPath).  Too high a value will cause reloadData to
        //be called more times than needed (as more rows become visible).  The best value is an
        //average of real cell sizes.
        NSNumber *height = [heightForRowCache objectForKey:[NSNumber numberWithInt:indexPath.row]];
        if (height != nil) {
            return height.floatValue;
        }
    
        return 200.0;
    }

    formato tableview:cellForRowAtIndexPath:

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        //Get a reusable cell
        UITableViewCell *currentCell = [tableView dequeueReusableCellWithIdentifier:_filter.templateName];
        if (currentCell == nil) {
            currentCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:_filter.templateName];
        }
    
        //Configure the cell
        //+++ unlisted method sets maxElementBottom & minElementTop +++
        [self configureCellElementLayout:currentCell withIndexPath:indexPath];
    
        //Calculate the new cell height
        NSNumber *newHeight = [NSNumber numberWithInt:maxElementBottom - minElementTop];
    
        //When the height of a cell changes (or is calculated for the first time) add a
        //reloadData request to the event queue.  This will cause heightForRowAtIndexPath
        //to be called again and inform the table of the new heights (after this refresh
        //cycle is complete since it's already been called for the current one).  (Calling
        //reloadData directly can work, but causes a reload for each new height)
        NSNumber *key = [NSNumber numberWithInt:indexPath.row];
        NSNumber *oldHeight = [heightForRowCache objectForKey:key];
        if (oldHeight == nil || newHeight.intValue != oldHeight.intValue) {
            if (!reloadRequested) {
                [self.tableView performSelector:@selector(reloadData) withObject:nil afterDelay:0];
                reloadRequested = TRUE;
            }
        }
    
        //Save the new height in the cache
        [heightForRowCache setObject:newHeight forKey:key];
    
        NSLog(@"cellForRow: %@ height=%@ >> %@", indexPath, oldHeight, newHeight);
    
        return currentCell;
    }
  7. 2

    Muy buena pregunta: en busca de una visión más clara sobre esto.

    Para aclarar el tema:

    1. Altura de la Fila se llama Antes de la (cellForRowAtIndexPath)
    2. La mayoría de la gente calcular la altura del tipo de información dentro de la CÉLULA (cellForRowAtIndexPath).

    Algunas de las soluciones son sorprendentemente simples y efectivas:

    • solución 1: la fuerza de la heightForRowAtIndexPath para calcular la de la célula especificaciones. Massimo Cafaro Sept 9

    • solución 2: ¿un primer paso «tamaño estándar» para las células, caché de resultados cuando se tienen alturas de celda, a continuación, volver a cargar la tabla utilizando las nuevas alturas – Simétrica

    • solución 3: el otro interesante respuesta parece ser que la participación de three20 pero basado en la respuesta parece ser que no hay una celda dibujado en el guión gráfico/xib que haría de este «problema» es mucho más fácil de resolver.

    • Gracias tiago – y, por cierto, solución 1 trabajó como un encanto. Después de que las palabras, había algunos más siguen en la questions acerca de algunos de desplazamiento de los problemas que el mal estado de algunos de mis etiquetas.
    • Aclarar en solución 1: su UITableViewCell subclase debe tener un método de clase para calcular su altura en función de los datos adecuados porque al llamar a cellForRowAtIndexPath (para obtener una instancia y el uso de un método de instancia) se los tiro en un bucle infinito.
  8. 0

    Me fui con la idea que me propuso originalmente, que parece que funciona bien, cual me carga todos la costumbre de las células antes de tiempo en la viewDidLoad, almacenarlos en un NSMutableDictionary con su índice de la clave. Estoy publicando el código correspondiente y el amor de cualquier críticas u opiniones, cualquiera que tenga acerca de este enfoque. Específicamente, no estoy seguro de si hay cualquier problema de pérdida de memoria con la manera en que yo estoy creando el UITableViewCells de la punta en viewDidLoad – ya no me suelta.

    @interface RecentController : UIViewController <UITableViewDelegate, UITableViewDataSource> {
    NSArray *listData;
    NSMutableDictionary *cellBank;
    }
    @property (nonatomic, retain) NSArray *listData;
    @property (nonatomic, retain) NSMutableDictionary *cellBank;
    @end
    @implementation RecentController
    @synthesize listData;
    @synthesize cellBank;
    ---
    - (void)viewDidLoad {
    ---
    self.cellBank = [[NSMutableDictionary alloc] init];
    ---
    //create question objects…
    --- 
    NSArray *array = [[NSArray alloc] initWithObjects:question1,question2,question3, nil];
    self.listData = array;
    //Pre load all table row cells
    int count = 0;
    for (id question in self.listData) {
    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"QuestionHeaderCell" 
    owner:self 
    options:nil];
    QuestionHeaderCell *cell;
    for (id oneObject in nib) {
    if([oneObject isKindOfClass:[QuestionHeaderCell class]])
    cell = (QuestionHeaderCell *) oneObject;
    NSNumber *key = [NSNumber numberWithInt:count];
    [cellBank setObject:[QuestionHeaderCell makeCell:cell 
    fromObject:question] 
    forKey:key];
    count++;
    }
    }
    [array release];
    [super viewDidLoad];
    }
    #pragma mark -
    #pragma mark Table View Data Source Methods
    -(NSInteger) tableView: (UITableView *) tableView
    numberOfRowsInSection: (NSInteger) section{
    return [self.listData count];
    }
    -(UITableViewCell *) tableView: (UITableView *) tableView
    cellForRowAtIndexPath: (NSIndexPath *) indexPath{
    NSNumber *key = [NSNumber numberWithInt:indexPath.row];
    return [cellBank objectForKey:key];
    }
    -(CGFloat) tableView: (UITableView *) tableView
    heightForRowAtIndexPath: (NSIndexPath *) indexPath{
    NSNumber *key = [NSNumber numberWithInt:indexPath.row];
    return [[cellBank objectForKey:key] totalCellHeight];
    }
    @end
    @interface QuestionHeaderCell : UITableViewCell {
    UITextView *title;
    UILabel *createdBy;
    UILabel *category;
    UILabel *questionText;
    UILabel *givenBy;
    UILabel *date;
    int totalCellHeight;
    }
    @property (nonatomic, retain) IBOutlet UITextView *title;
    @property (nonatomic, retain) IBOutlet UILabel *category;
    @property (nonatomic, retain) IBOutlet UILabel *questionText;
    @property (nonatomic, retain) IBOutlet UILabel *createdBy;
    @property (nonatomic, retain) IBOutlet UILabel *givenBy;
    @property (nonatomic, retain) IBOutlet UILabel *date;
    @property int totalCellHeight;
    +(UITableViewCell *) makeCell:(QuestionHeaderCell *) cell 
    fromObject:(Question *) question;
    @end
    @implementation QuestionHeaderCell
    @synthesize title;
    @synthesize createdBy;
    @synthesize givenBy;
    @synthesize questionText;
    @synthesize date;
    @synthesize category;
    @synthesize totalCellHeight;
    - (void)dealloc {
    [title release];
    [createdBy release];
    [givenBy release];
    [category release];
    [date release];
    [questionText release];
    [super dealloc];
    }
    +(UITableViewCell *) makeCell:(QuestionHeaderCell *) cell 
    fromObject:(Question *) question{
    NSUInteger currentYpos = 0;
    cell.title.text = question.title;
    CGRect frame = cell.title.frame;
    frame.size.height = cell.title.contentSize.height;
    cell.title.frame = frame;
    currentYpos += cell.title.frame.size.height + 2;
    NSMutableString *tempString = [[NSMutableString alloc] initWithString:question.categoryName];
    [tempString appendString:@"/"];
    [tempString appendString:question.subCategoryName];
    cell.category.text = tempString;
    frame = cell.category.frame;
    frame.origin.y = currentYpos;
    cell.category.frame = frame;
    currentYpos += cell.category.frame.size.height;
    [tempString setString:@"Asked by "];
    [tempString appendString:question.username];
    cell.createdBy.text = tempString;
    frame = cell.createdBy.frame;
    frame.origin.y = currentYpos;
    cell.createdBy.frame = frame;
    currentYpos += cell.createdBy.frame.size.height;
    cell.questionText.text = question.text;
    frame = cell.questionText.frame;
    frame.origin.y = currentYpos;
    cell.questionText.frame = frame;
    currentYpos += cell.questionText.frame.size.height;
    [tempString setString:@"Advice by "];
    [tempString appendString:question.lastNexusUsername];
    cell.givenBy.text = tempString;
    frame = cell.givenBy.frame;
    frame.origin.y = currentYpos;
    cell.givenBy.frame = frame;
    currentYpos += cell.givenBy.frame.size.height;
    cell.date.text = [[[MortalDataStore sharedInstance] dateFormat] stringFromDate: question.lastOnDeck];
    frame = cell.date.frame;
    frame.origin.y = currentYpos-6;
    cell.date.frame = frame;
    currentYpos += cell.date.frame.size.height;
    //Set the total height of cell to be used in heightForRowAtIndexPath
    cell.totalCellHeight = currentYpos;
    [tempString release];
    return cell;
    }
    @end
    • Este es un enorme desperdicio de memoria y totalmente subvierte el punto entero de la celda de la tabla de almacenamiento en caché de rendimiento.
  9. 0

    Aquí es lo que tengo que hacer en caso muy simple, una celda que contiene una nota a cabo en una etiqueta. La nota en sí es limitada a un máximo de longitud estoy imponiendo, por lo que uso una multi-línea UILabel y puedo calcular de forma dinámica la correcta ocho de cada celda, como se muestra en el siguiente ejemplo. Usted puede tratar de un UITextView prácticamente en el mismo.

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
    }
    //Configure the cell...
    Note *note = (Note *) [fetchedResultsController objectAtIndexPath:indexPath];
    cell.textLabel.text = note.text;
    cell.textLabel.numberOfLines = 0; //no limits
    DateTimeHelper *dateTimeHelper = [DateTimeHelper sharedDateTimeHelper];
    cell.detailTextLabel.text = [dateTimeHelper mediumStringForDate:note.date];
    cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
    return cell;
    }
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    //NSLog(@"heightForRowAtIndexPath: Section %d Row %d", indexPath.section, indexPath.row);
    UITableViewCell *cell = [self tableView: self.tableView cellForRowAtIndexPath: indexPath];
    NSString *note = cell.textLabel.text;
    UIFont *font = [UIFont fontWithName:@"Helvetica" size:14.0];
    CGSize constraintSize = CGSizeMake(280.0f, MAXFLOAT);
    CGSize bounds = [note sizeWithFont:font constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];
    return (CGFloat) cell.bounds.size.height + bounds.height;
    }
    • ¿Esto realmente funcione para usted, porque me llego un bucle infinito cuando se llama a cellForRowAtIndexPath en heightForRowAtIndexPath?
    • Este hecho se usa en dos aplicaciones disponibles en la AppStore y que habitualmente utilizado por miles, así que estoy bastante seguro de que su trabajo. Se ha probado en iOS 4.2.x y 4.3.x.
    • También tengo un bucle infinito de utilizar este método con iOS 5+
  10. 0

    como he buscado más y más acerca de este tema, finalmente esta lógica, vino a mi pensamiento. un código simple, pero tal vez no lo suficientemente eficiente, pero hasta ahora es la mejor que puedes encontrar.

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
    NSDictionary * Object=[[NSDictionary alloc]init];
    Object=[Rentals objectAtIndex:indexPath.row];
    static NSString *CellIdentifier = @"RentalCell";
    RentalCell *cell = (RentalCell *)[tableView
    dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil)
    {
    cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    }
    NSString* temp=[Object objectForKey:@"desc"];
    int lines= (temp.length/51)+1;
    //so maybe here, i count how many characters that fit in one line in this case 51
    CGRect correctSize=CGRectMake(cell.infoLabel.frame.origin.x, cell.infoLabel.frame.origin.y,    cell.infoLabel.frame.size.width, (15*lines));
    //15 (for new line height)
    [cell.infoLabel setFrame:correctSize];
    //manage your cell here
    }

    y aquí está el resto del código

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    NSDictionary * Object=[[NSDictionary alloc]init];
    Object=[Rentals objectAtIndex:indexPath.row];
    static NSString *CellIdentifier = @"RentalCell";
    RentalCell *cells = (RentalCell *)[tableView
    dequeueReusableCellWithIdentifier:CellIdentifier];
    NSString* temp=[Object objectForKey:@"desc"];
    int lines= temp.length/51;
    return (CGFloat) cells.bounds.size.height + (13*lines);
    }
    • Este es realmente lento. A pesar de que la celda se llama dos veces.

Dejar respuesta

Please enter your comment!
Please enter your name here