ios uitableview ios8

iOS8: ¿Se puede usar "tableview.rowHeight=UITableViewAutomaticDimension" para celdas estáticas?



(8)

Tengo un UITableView que tiene cinco celdas estáticas. Necesito la altura de celda de una celda para ajustarme automáticamente a su contenido, que es una UILabel.

¿Hay alguna manera de que pueda usar ...

tableView.estimatedRowHeight = 42.0 tableView.rowHeight = UITableViewAutomaticDimension

..para una vista de tabla con celdas estáticas, o esto solo funciona para vistas de tabla con celdas dinámicas prototipo?

(¿O hay alguna otra forma de hacerlo que recomendarías?)

información adicional

El UITableView está en un TableViewController que está incrustado en una vista de contenedor.

Las cinco celdas estáticas son bastante diferentes entre sí y solo se usan en una escena de la aplicación, por lo que no veo mucho sentido en el uso de prototipos dinámicos y subclases de celdas personalizadas.

Actualizo la vista de tabla como esta

-(void) viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; [_myTableView reloadData]; }

Agrego restricciones a la UILabel como se describe aquí: http://www.appcoda.com/self-sizing-cells/


Acabé haciendo esto. No es lo que quería, pero funciona para mis requisitos simples y longitudes de texto.

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.row == 2) { CGFloat padding = 30.0f; CGFloat labelWidth = self.tableView.bounds.size.width - padding*2; NSAttributedString *text = [[NSAttributedString alloc] initWithString:_freeTextLabel.text]; NSStringDrawingOptions options = NSStringDrawingUsesLineFragmentOrigin; CGRect boundingRect = [text boundingRectWithSize:CGSizeMake(labelWidth, CGFLOAT_MAX) options:options context:nil]; return (CGFloat) (ceil(boundingRect.size.height) + padding*2); } return [super tableView:tableView heightForRowAtIndexPath:indexPath]; }


Ampliando sobre la respuesta de Victors, las vistas de tabla basadas en células estáticas parecen auto-dimensionar las células según el contenido y las restricciones una vez que se implementan los siguientes delegados:

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return UITableViewAutomaticDimension; } -(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath { return 44; }

EXCEPTO para cuando haya etiquetas. Por alguna razón, las alturas de contenido intrínseco de la etiqueta no parecen contribuir al cálculo de la altura de la celda cuando tienen. Mi trabajo actual para esto es anidar las etiquetas en una vista UIV.

Haz lo siguiente:

  1. Incrustar la etiqueta (o etiquetas) en una vista. (Seleccione las etiquetas en IB y presione Menú> Editor> Incrustar en> Ver)
  2. Establecer restricciones de margen horizontal y vertical entre esta vista y la celda
  3. Establezca restricciones de margen horizontales y verticales entre sus etiquetas y esta vista.

Ciertamente se siente como un truco, pero funciona para mí en todos los casos que he intentado.


Aquí hay un ejemplo simple con Swift 3. Tenemos un UITableViewController en Storyboard configurado con tipo agrupado y contenido de tipo celdas estáticas . Su tableView contiene un UITableViewCell . La celda contiene una UILabel que tiene una serie de líneas configuradas en 0 y un texto muy largo para mostrar. La etiqueta también tiene cuatro restricciones de diseño automático con su superView ( superior , inferior , anterior y posterior ).

Ahora, puede elegir uno de los cuatro fragmentos de código siguientes para permitir que su celda estática se redimensione automáticamente de acuerdo con su contenido.

# 1. Usando tableView(_:estimatedHeightForRowAt:) tableView(_:heightForRowAt:) tableView(_:estimatedHeightForRowAt:) y tableView(_:heightForRowAt:)

Nota: el tableView(_:estimatedHeightForRowAt:) : tableView(_:estimatedHeightForRowAt:) requiere iOS7

import UIKit class TableViewController: UITableViewController { override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return UITableViewAutomaticDimension } override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat { return 100 // Return `UITableViewAutomaticDimension` if you have no estimate } }

# 2. Uso de la propiedad tableView(_:heightForRowAt:) y tableView(_:heightForRowAt:)

Nota: la propiedad verifiedRowHeight requiere iOS7

import UIKit class TableViewController: UITableViewController { override func viewDidLoad() { super.viewDidLoad() tableView.estimatedRowHeight = 100 } override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return UITableViewAutomaticDimension } }

# 3. Usando tableView(_:heightForRowAt:)

import UIKit class TableViewController: UITableViewController { // Bind this IBOutlet to the cell in Storyboard @IBOutlet weak var cell: UITableViewCell! override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { let fittingSize = CGSize(width: tableView.bounds.size.width, height: 0) let systemLayoutSize = cell.systemLayoutSizeFitting(fittingSize, withHorizontalFittingPriority: UILayoutPriorityRequired, verticalFittingPriority: UILayoutPriorityFittingSizeLevel) return systemLayoutSize.height } }

# 4. Usando la subclase UITableViewCell y tableView(_:heightForRowAt:)

import UIKit class TableViewController: UITableViewController { // 1. Set custom class to `CustomCell` for cell in Storyboard // 2. Bind this IBOutlet to the cell in Storyboard @IBOutlet weak var cell: CustomCell! override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { cell.layoutIfNeeded() let contentViewSize = cell.contentView.systemLayoutSizeFitting(UILayoutFittingCompressedSize) return contentViewSize.height + 1 // + 1 for the separator } } class CustomCell: UITableViewCell { // 1. Set custom class to `CustomCell` for cell in Storyboard // 2. Bind this IBOutlet to the cell''s label in Storyboard @IBOutlet weak var label: UILabel! override func layoutSubviews() { super.layoutSubviews() label.preferredMaxLayoutWidth = frame.width } }

Los cuatro fragmentos de código anteriores darán como resultado la siguiente visualización:


En IOS8, encontré que establecer explícitamente la altura / anchura de la fila o la altura / anchura de la etiqueta en el código causa más problemas de los que soluciona. He creado tablas dinámicas y estáticas con altura variable de celda y etiquetas multilínea utilizando autolayout, pero realmente tienes que seguir el estándar de Apple para que ocurran cosas extrañas (como la desaparición de los separadores o las filas que colapsan aleatoriamente en altura).

  • [editado] Establezca estimadoHeightForRowAtIndexPath y heightForRowAtIndexPath a las dimensiones automáticas en su UITableViewDelegate

    override func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { return UITableViewAutomaticDimension } override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { return UITableViewAutomaticDimension }

  • Asegúrese de que cada elemento de la celda tenga una restricción superior / inferior / izquierda / derecha = (no> =, <=, o alignX o alignY - tiene que ser =). Puede hacer que esto sea una restricción de baja prioridad y proporcionar una mejor restricción de mayor prioridad, pero tiene que darle un valor inicial exacto para dimensionar la celda.


Para iOS 8, descubrí que no se puede hacer la misma estrategia que para la celda de vista de tabla dinámica.

Para ajustar automáticamente la altura de las celdas estáticas, implemento estos dos métodos UITableViewDelegate:

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return UITableViewAutomaticDimension; } -(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath { return 44; }

Espero eso ayude.


Supongo que necesitaría decirle a la celda que vuelva a dibujar usando algo como

[self.tableView beginUpdates]; [self.tableView reloadRowsAtIndexPaths:@[indexPathOfYourCell] withRowAnimation:UITableViewRowAnimationNone]; [self.tableView endUpdates];

Cuando se trata de cambiar dinámicamente la altura de las celdas de visualización de tabla.

-(CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return Yourvalue; //return whatever u want ur cell to have size. }


También estaba buscando una respuesta para esto y encontré esta solución, que probé y funciona perfectamente en iOS8.

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.row == 2) //Dynamic Height { return UITableViewAutomaticDimension; } else { return 50; // Static Height } }


NOTA : Esto se basa en la respuesta de @CamelBase, que está escrita para Objective-C, así que en su mayoría es solo una conversión a Swift para aquellos que hicieron el cambio y aún luchan por convertir cosas por sí mismos.

Para aquellos que quieran hacer esto usando Swift que quieren una tabla con celdas estáticas, aquí hay una solución de trabajo.

No necesité usar este código (intenté ponerlo en viewDidLoad() y lo intenté sin, no hizo ninguna diferencia):

tableView.estimatedRowHeight = 42.0 tableView.rowHeight = UITableViewAutomaticDimension

Primero desea agregar UILabel a cada celda en la que desee que el contenido crezca automáticamente.

Deberá agregar 4 restricciones a la UILabel, todas relacionadas con la principal (Vista de contenido de la celda).

  • Margen inicial 0
  • Margen final 0
  • Margen superior 0
  • Margen Inferior 0

Esto hará que la etiqueta crezca cuando crezca la celda (lo que hace nuestro código a continuación).

Ahora solo agrega este código:

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { let sectionICareAbout = 2 let rowICareAbout = 1 // repeat for as many section/row combos you need dynamic sizing on if indexPath.section == sectionICareAbout && indexPath == rowICareAbout { // replace with how you get the content for the cell // in section 2 row 1 let text = "line1/nline2/nline3" return rowHeightForText(text) } // use auto-dimension if we didn''t set something else return UITableViewAutomaticDimension } func rowHeightForText(text: String) -> CGFloat { let labelWidth = tableView.bounds.size.width let attributedText = NSAttributedString(string: text) let options = NSStringDrawingOptions.UsesLineFragmentOrigin let size = CGSize(width: labelWidth, height: CGFloat.max) let boundingRect = attributedText.boundingRectWithSize(size, options: options, context: nil) return boundingRect.size.height }