ios - uitableviewcell - uitableviewautomaticdimension not working
Problema de altura dinĂ¡mica para celdas UITableView(Swift) (24)
Se está inyectando texto dinámico de longitud variable en las etiquetas de celda de vista de tabla.
Para que las alturas de las celdas de la vista de tabla tengan un tamaño dinámico, he implementado en
viewDidLoad()
:
self.tableView.estimatedRowHeight = 88.0
self.tableView.rowHeight = UITableViewAutomaticDimension
Esto funciona bien para las celdas que aún no se han desplazado (como se llama a
UITableViewAutomaticDimention
al desplazarse a la celda), pero no para las celdas que inicialmente se muestran en pantalla al cargar la tabla con datos.
He intentado simplemente volver a cargar los datos (como se sugiere en muchos otros recursos):
self.tableView.reloadData()
tanto en
viewDidAppear()
como en
viewWillAppear()
y fue en vano.
Estoy perdido ... ¿Alguien sabe cómo hacer que xcode represente la altura dinámica de las celdas cargadas inicialmente en la pantalla?
Avíseme si hay un método alternativo mejor.
Además de lo que otros han dicho,
¡CONFIGURE LAS RESTRICCIONES DE LA ETIQUETA EN RELACIÓN CON LA SUPERVISIÓN!
Por lo tanto, en lugar de colocar las restricciones de su etiqueta en relación con otras cosas a su alrededor, restringirla a la vista de contenido de la celda de la vista de tabla.
Luego, asegúrese de que la altura de su etiqueta esté establecida en más de o igual a 0, y que el número de líneas esté establecido en 0.
Luego en
ViewDidLoad
agregue:
tableView.estimatedRowHeight = 695
tableView.rowHeight = UITableViewAutomaticDimension
Cuando uso un
UITableView
estático, configuro todos los valores en
UILabel
sy luego llamo
tableView.reloadData()
.
En mi caso: en el guión gráfico tenía dos etiquetas como en la imagen a continuación, ambas etiquetas tenían los valores de ancho deseados establecidos antes de que fuera igual. una vez que se desmarca, cambiará a automático y, como siempre, tener las siguientes cosas debería funcionar a la perfección.
1.rowHeight = UITableView.automaticDimension, and
2.estimatedRowHeight = 100(In my case).
3.make sure label number of lines is zero.
Establezca la dimensión automática para la altura de la fila y la altura estimada de la fila y asegúrese de los siguientes pasos:
@IBOutlet weak var table: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Set automatic dimensions for row height
// Swift 4.2 onwards
table.rowHeight = UITableView.automaticDimension
table.estimatedRowHeight = UITableView.automaticDimension
// Swift 4.1 and below
table.rowHeight = UITableViewAutomaticDimension
table.estimatedRowHeight = UITableViewAutomaticDimension
}
// UITableViewAutomaticDimension calculates height of label contents/text
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
// Swift 4.2 onwards
return UITableView.automaticDimension
// Swift 4.1 and below
return UITableViewAutomaticDimension
}
Por ejemplo: si tiene una etiqueta en su UITableviewCell, entonces,
- Establecer número de líneas = 0 (& modo de salto de línea = truncar cola)
- Establezca todas las restricciones (arriba, abajo, derecha izquierda) con respecto a su contenedor de supervista / celda.
- Opcional : establezca la altura mínima para la etiqueta, si desea un área vertical mínima cubierta por la etiqueta, incluso si no hay datos.
Aquí hay una etiqueta de muestra con restricciones de altura dinámicas.
Establezca la restricción adecuada y actualice los métodos delegados como:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return UITableViewAutomaticDimension } func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat { return UITableViewAutomaticDimension }
Esto resolverá el problema de altura de celda dinámica. Si no, debe verificar las restricciones.
Este extraño error se resolvió mediante los parámetros de Interface Builder ya que las otras respuestas no resolvieron el problema.
Todo lo que hice fue hacer que el tamaño predeterminado de la etiqueta fuera más grande de lo que podría ser el contenido y que también se refleje en la altura
estimatedRowHeight
RowHeight.
Anteriormente, configuré el alto de fila predeterminado en Interface Builder en
88px
y lo
88px
así en mi controlador
viewDidLoad()
:
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.estimatedRowHeight = 88.0
Pero eso no funcionó.
Entonces me di cuenta de que el contenido nunca sería más grande que quizás
100px
, así que configuré la altura de celda predeterminada a
108px
(más grande que el contenido potencial) y lo
viewDidLoad()
así en la vista del controladorDidLoad
viewDidLoad()
:
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.estimatedRowHeight = 108.0
Esto realmente permitió que el código
redujera
las etiquetas iniciales al tamaño correcto.
En otras palabras, nunca se expandió a un tamaño mayor, pero siempre podría reducirse ... Además, no se necesitaba
viewWillAppear()
en
viewWillAppear()
.
Sé que esto no cubre tamaños de contenido muy variables, pero esto funcionó en mi situación en la que el contenido tenía un recuento de caracteres máximo posible.
No estoy seguro de si esto es un error en Swift o Interface Builder, pero funciona de maravilla. ¡Darle una oportunidad!
Esto es simple al hacer 2 cosas:
-
ajuste de la altura automática
tableView.rowHeight = UITableView.automaticDimension
-
creando todas las TableViewCells con restricciones COMPLETAS de arriba a abajo. El último elemento ** DEBE ** definir un espacio inferior para finalizar la celda.
Por lo tanto, el motor de diseño puede calcular la altura de la celda y aplicar el valor correctamente.
La celda de tamaño dinámico de UITableView requiere 2 cosas
- Establecer la restricción correcta de su vista dentro de la celda de la vista de tabla (principalmente incluye darle a su vista las restricciones superiores, inferiores y de arrastre adecuadas)
-
Llamar a estas propiedades de TableView en viewDidLoad ()
tableView.rowHeight = UITableViewAutomaticDimension tableView.estimatedRowHeight = 140
This es un tutorial maravilloso sobre auto-dimensionamiento (celdas de vista de tabla dinámica) escrito en swift 3.
Lamentablemente, no estoy seguro de lo que me estaba perdiendo. Los métodos anteriores no funcionan para mí para obtener la altura de la celda xib o dejar que layoutifneeded () o UITableView.automaticDimension hagan el cálculo de altura. He estado buscando e intentando durante 3 a 4 noches, pero no pude encontrar una respuesta. Sin embargo, algunas respuestas aquí o en otra publicación me dieron pistas para la solución. Es un método estúpido pero funciona. Simplemente agregue todas sus celdas en una matriz. Y luego configure la salida de cada una de sus restricciones de altura en el guión gráfico xib. Finalmente, agréguelos en el método heightForRowAt. Es sencillo si no está familiarizado con esas API.
Swift 4.2
CustomCell.Swift
@IBOutlet weak var textViewOneHeight: NSLayoutConstraint!
@IBOutlet weak var textViewTwoHeight: NSLayoutConstraint!
@IBOutlet weak var textViewThreeHeight: NSLayoutConstraint!
@IBOutlet weak var textViewFourHeight: NSLayoutConstraint!
@IBOutlet weak var textViewFiveHeight: NSLayoutConstraint!
MyTableViewVC.Swift
.
.
var myCustomCells:[CustomCell] = []
.
.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = Bundle.main.loadNibNamed("CustomCell", owner: self, options: nil)?.first as! CustomCell
.
.
myCustomCells.append(cell)
return cell
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
let totalHeight = myCustomCells[indexPath.row].textViewOneHeight.constant + myCustomCells[indexPath.row].textViewTwoHeight.constant + myCustomCells[indexPath.row].textViewThreeHeight.constant + myCustomCells[indexPath.row].textViewFourHeight.constant + myCustomCells[indexPath.row].textViewFiveHeight.constant
return totalHeight + 40 //some magic number
}
Para Swift 3 puede usar lo siguiente:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
Para Swift 4.2
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
Happy Coding :)
Para Swift, verifiqué esta respuesta en iOS 9.0 y iOS 11 también (Xcode 9.3)
@IBOutlet weak var tableVw: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Set self as tableView delegate
tableVw.delegate = self
tableVw.rowHeight = UITableView.automaticDimension
tableVw.estimatedRowHeight = UITableView.automaticDimension
}
// UITableViewDelegate Method
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
Aquí debe agregar restricciones superiores, inferiores, derecha e izquierda
Para el objetivo c, esta es una de mis buenas soluciones. Me ha funcionado.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
cell.textLabel.text = [_nameArray objectAtIndex:indexPath.row];
cell.textLabel.numberOfLines = 0;
cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewAutomaticDimension;
}
Necesitamos aplicar estos 2 cambios.
1)cell.textLabel.numberOfLines = 0;
cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping;
2)return UITableViewAutomaticDimension;
Para que funcione la autoresize de UITableViewCell, asegúrese de realizar estos cambios:
- En Storyboard, su UITableView solo debe contener celdas de prototipo dinámico (no debe usar celdas estáticas), de lo contrario, la función de autorizar no funcionará.
- En Storyboard, su UILabel de UITableViewCell se ha configurado para las 4 restricciones que son las restricciones superior, inferior, inicial y final.
- En Storyboard, el número de líneas UILabel de UITableViewCell debe ser 0
-
En la función viewDidLoad de su UIViewController establecida debajo de las Propiedades de UITableView:
self.tableView.estimatedRowHeight = <minimum cell height> self.tableView.rowHeight = UITableViewAutomaticDimension
Prueba esto:
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
EDITAR
func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
Swift 4
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
Swift 4.2
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
Definir por encima de ambos métodos.
Soluciona el problema.
PD: Se requieren restricciones superiores e inferiores para que esto funcione.
SWIFT 3
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 160
¡¡¡Y!!! En storyBoard: TIENES QUE establecer restricciones TOP & BOTTOM para tu etiqueta. Nada más.
Simplemente debe establecer todas las restricciones para SUPERIOR , INFERIOR y ALTURA para cada objeto en la vista / vistas de celda y eliminar la posición Y central si la tiene. Porque donde no lo hiciste, pone artefactos en otras vistas.
Su solución me inspiró y probé de otra manera.
Intente agregar
tableView.reloadData()
para
viewDidAppear()
.
Esto funciona para mi.
Creo que las cosas detrás del desplazamiento son "lo mismo" que reloadData.
Cuando desplaza la pantalla, es como llamar a
reloadData()
cuando
viewDidAppear
.
Si esto funciona, por favor responda esta respuesta para poder estar seguro de esta solución.
También tuve este problema inicialmente, resolví mi problema con este código, intente evitar el uso de
self.tableView.reloadData()
lugar de este código para la altura dinámica
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationFade];
Tratar
override func viewWillAppear(animated: Bool) {
self.tableView.layoutSubviews()
}
Tuve el mismo problema y me funciona.
Utilizar este:
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 300
y no use: función de delegado
heightForRowAtIndexPath
Además, en el guión gráfico no establezca la altura de la etiqueta que contiene una gran cantidad de datos.
Déle restricciones
top, bottom, leading, trailing
.
Yo uso estos
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 100
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
enter code here self.Itemtableview.estimatedRowHeight = 0;
self.Itemtableview.estimatedSectionHeaderHeight = 0;
self.Itemtableview.estimatedSectionFooterHeight = 0;
[ self.Itemtableview reloadData];
self.Itemtableview.frame = CGRectMake( self.Itemtableview.frame.origin.x, self.Itemtableview.frame.origin.y, self.Itemtableview.frame.size.width,self.Itemtableview.contentSize.height + self.Itemtableview.contentInset.bottom + self.Itemtableview.contentInset.top);
Y no olvide agregar restricciones de botones para la etiqueta