ios uitableview ios8 autolayout

ios - ¿Es posible obtener una altura de encabezado de sección de vista de tabla dinámica usando Diseño automático?



uitableview ios8 (8)

Nuevo en iOS 8, puede obtener celdas de vista de tabla 100% dinámicas simplemente configurando la altura de fila estimada, luego diseñe sus elementos en la celda usando Diseño automático. Si el contenido aumenta en altura, la celda también aumentará en altura. Esto es extremadamente útil, y me pregunto si se puede lograr la misma hazaña para los encabezados de sección en una vista de tabla.

¿Se puede, por ejemplo, crear una UIView en tableView:viewForHeaderInSection: agregar una subvista UILabel , especificar restricciones de diseño automático para la etiqueta contra la vista y hacer que la vista aumente en altura para ajustarse al contenido de la etiqueta, sin tener que implementar tableView:heightForHeaderInSection: :?

La documentación de viewForHeaderInSection establece: "Este método solo funciona correctamente cuando tableView: heightForHeaderInSection: también está implementado". No he escuchado si algo ha cambiado para iOS 8.

Si uno no puede hacer eso, ¿cuál es la mejor manera de imitar este comportamiento?


En mi caso:

  1. establecer programáticamente no funciona .

self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension .

  1. establecido en el guión gráfico no funciona .

  2. anular heightForHeaderInSection trabajado .

override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { return UITableViewAutomaticDimension }

entorno de prueba:

  • Mac OS 10.13.4
  • XCode Versión 9.4.1
  • Simulador de iPhone 8 Plus

Esto es posible. Es nuevo junto con las alturas de celda dinámicas implementadas en iOS 8.

Es muy sencillo. Simplemente agregue esto en viewDidLoad :

self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension; self.tableView.estimatedSectionHeaderHeight = 25;

Luego, anule viewForHeaderInSection y use Diseño automático para restringir los elementos en su vista como se ve. ¡Eso es! No es necesario implementar heightForHeaderInSection . Y en realidad la sectionHeaderHeight tampoco necesita ser declarada, simplemente la agregué para mayor claridad.

Tenga en cuenta que en iOS 11, las vistas de celdas y encabezados / pies de página usan alturas estimadas de forma predeterminada. Lo único que debe hacer es proporcionar una altura estimada para informar mejor al sistema qué esperar. El valor predeterminado es UITableViewAutomaticDimension pero debe proporcionar una mejor estimación de la altura promedio que tendrán si es posible.


Esto se puede lograr estableciendo (o devolviendo) el estimatedSectionHeaderHeight en su vista de tabla.

Si el encabezado de la sección se superpone a las celdas después de establecer el valor estimatedSectionHeaderHeight SectionHeaderHeight , asegúrese de utilizar también un estimatedRowHeight .

(Estoy agregando esta respuesta porque el segundo párrafo contiene una respuesta a un problema que se puede encontrar después de leer todos los comentarios que algunos podrían pasar por alto).


Lo intenté

self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension; self.tableView.estimatedSectionHeaderHeight = 25;

pero no dimensionó correctamente el encabezado con etiqueta multilínea. Agregué esto para resolver mi problema:

override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) // Recalculates height tableView.beginUpdates() tableView.endUpdates() }


Me quedé atrapado en el mismo problema donde el encabezado obtenía una altura cero hasta que y a menos que proporcione una altura fija en el delegado para heighForHeaderInSection .

Probé muchas soluciones que incluyen

self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension; self.tableView.estimatedSectionHeaderHeight = 73`

Pero nada funcionó. Mi celular también estaba usando los autolayouts adecuados. Las filas estaban cambiando su altura dinámicamente usando el siguiente código, pero el encabezado de la sección no.

self.tableView.estimatedRowHeight = 135 self.tableView.rowHeight = UITableViewAutomaticDimension`

La solución es extremadamente simple y extraña también, pero tuve que implementar los métodos de delegado en lugar del código de 1 línea para el estimatedSectionHeaderHeight sectionHeaderHeight y sectionHeaderHeight que es el siguiente para mi caso.

func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { return UITableViewAutomaticDimension } func tableView(_ tableView: UITableView, estimatedHeightForHeaderInSection section: Int) -> CGFloat { return 73 }


Si, funciona para mi. Tengo que hacer más cambios de la siguiente manera:

override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { let label = UILabel() label.numberOfLines = 0 label.text = my own text return label }


answer . Acabo de reemplazar el método viewWillAppear:

tableView.sectionHeaderHeight = UITableViewAutomaticDimension tableView.estimatedSectionHeaderHeight = 25 override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) // Recalculates height tableView.layoutIfNeeded() }

Agregue también tableView.layoutIfNeeded () a

override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) tableView.layoutIfNeeded() }

Para iOS 10

tableView.beginUpdates() tableView.endUpdates()

tener un efecto de animación "desvanecerse" en la vista Aparecerá para mí


Swift 4+

trabajando (probado 100%)

Si necesita tanto la sección como la fila con altura dinámica basada en el contenido, puede usar el siguiente código:

En viewDidLoad () escribe estas líneas:

self.globalTableView.estimatedRowHeight = 20 self.globalTableView.rowHeight = UITableView.automaticDimension self.globalTableView.sectionHeaderHeight = UITableView.automaticDimension self.globalTableView.estimatedSectionHeaderHeight = 25;

Ahora hemos establecido el alto de fila y el alto de sección utilizando los métodos de UITableView Delegate:

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return UITableView.automaticDimension } func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { return UITableView.automaticDimension }