uitableviewcell resizing different ios uitableview autolayout

ios - resizing - uitableviewautomaticdimension



UILabel en UITableViewCell con diseño automático tiene una altura incorrecta (4)

Tengo un UITableView con celdas que tienen una altura fija de 100 puntos. Las celdas se crean en un archivo xib que usa 3 restricciones para anclar un UILabel a los bordes izquierdo, derecho y superior del contentView de la celda. La prioridad vertical de la etiqueta se establece en 1000 porque quiero que la altura de la celda sea lo más pequeña posible.

Cuando el ancho de la celda en el archivo xib se establece en 320 puntos, al igual que el ancho de tableView en el iPhone, la reproducción automática funciona como se espera. Sin embargo, cuando configuro el ancho de la celda en menos de 320 puntos, obtengo resultados inesperados. (Quiero usar la misma celda en las vistas de tabla que tienen diferentes anchos, por ejemplo, en una aplicación universal)

Por ejemplo: cuando establezco el ancho en 224 puntos y le doy a la etiqueta un texto que ocupa 2 líneas en ese ancho, la altura de la etiqueta aumentará para ajustarse a las 2 líneas, pero cuando la celda se redimensione a 320 puntos para adaptarse una vista de tabla de ese ancho, el texto solo ocupa 1 línea, pero el alto de la etiqueta permanece en 2 líneas.

He puesto un proyecto de muestra en GitHub para demostrar el problema: https://github.com/bluecrowbar/CellLayout

¿Hay alguna manera de hacer que la UILabel siempre UILabel tamaño para UILabel contenido del texto?


¡Estúpido bicho! Perdí casi un día en este problema y finalmente lo resolví con la solución de Steven Vandewghe.

Versión rápida:

override func layoutSubviews() { super.layoutSubviews() self.contentView.layoutIfNeeded() self.myLabel.preferredMaxLayoutWidth = self.myLabel.frame.size.width }


Añadiendo esto en la subclase de celda funciona:

- (void)layoutSubviews { [super layoutSubviews]; [self.contentView layoutIfNeeded]; self.myLabel.preferredMaxLayoutWidth = self.myLabel.frame.size.width; }

Encontré esto en http://useyourloaf.com/blog/2014/02/14/table-view-cells-with-varying-row-heights.html .

Actualización 1: esta respuesta fue para iOS 7. Creo que el diseño automático en las celdas de vista de tabla es muy poco confiable desde iOS 8, incluso para diseños muy simples. Después de mucha experimentación, (en su mayoría) volví a hacer el diseño manual y el cálculo manual de la altura de la celda.

Actualización 2: he ejecutado algunas pruebas en iOS 9 y parece que UITableViewAutomaticDimension finalmente funciona como se anuncia. ¡Hurra!


Como está restringiendo el width la etiqueta, intrinsicContentSize respeta ese width y ajusta la height . Y esto plantea un problema de huevo y gallina:

  1. El resultado de Auto Layout de la celda depende de la etiqueta intrinsicContentSize
  2. El tamaño del contenido intrinsicContentSize de la etiqueta depende del width la etiqueta
  3. El width la etiqueta depende del resultado del diseño automático de la celda

Entonces, lo que sucede es que el diseño de la celda solo se calcula una vez en la que (2) se basa en el ancho estático en el archivo XIB y esto da como resultado una height etiqueta incorrecta.

Puedes resolver esto iterando. Es decir, repita el cálculo de Disposición automática una vez que el width la etiqueta haya sido establecido por el primer cálculo. Algo como esto en tu celda personalizada funcionará:

- (void)drawRect:(CGRect)rect { CGSize size = self.myLabel.bounds.size; // tell the label to size itself based on the current width [self.myLabel sizeToFit]; if (!CGSizeEqualToSize(size, self.myLabel.bounds.size)) { [self setNeedsUpdateConstraints]; [self updateConstraintsIfNeeded]; } [super drawRect:rect]; }

La solución original no funciona de manera confiable:

- (void)layoutSubviews { [super layoutSubviews]; // check for need to re-evaluate constraints on next run loop // cycle after the layout has been finalized dispatch_async(dispatch_get_main_queue(), ^{ CGSize size = self.myLabel.bounds.size; // tell the label to size itself based on the current width [self.myLabel sizeToFit]; if (!CGSizeEqualToSize(size, self.myLabel.bounds.size)) { [self setNeedsUpdateConstraints]; [self updateConstraintsIfNeeded]; } }); }


Normalmente agrego estas dos líneas a viewDidLoad ()

self.tableView.rowHeight = UITableViewAutomaticDimension self.tableView.estimatedRowHeight = 96

Esto cambiará automáticamente el tamaño de la celda