Swift: tamaño UMImageView dynamic dentro de UITableView

Estoy buscando su ayuda en este tema porque he estado luchando bastante time. Quiero implementar un TableView con un TableViewCell personalizado que muestre una image.

Para hacer esto simple, simplemente coloco una UIImageView dentro de una tablaviewcell usando autolayout (ilustrada a continuación). introduzca la descripción de la imagen aquí

Lo que quiero es mostrar la image dentro de un UIImageView, sin embargo esas dimensiones de imágenes pueden ser cualquier cosa y no son consistentes (retrato, paisaje, cuadrado) …

Por lo tanto, estoy buscando mostrar una image con un ancho fijo (el ancho del dispositivo) y una altura dinámica que respete la relación de las imágenes. Quiero algo como esto: introduzca la descripción de la imagen aquí

Desafortunadamente no logré alcanzar ese resultado.

Así es como lo implementé (estoy usando Haneke para cargar la image de una URL almacenada en Amazon S3):

class TestCellVC: UITableViewCell { @IBOutlet weak var selfieImageView: UIImageView! @IBOutlet weak var heightConstraint: NSLayoutConstraint! func loadItem(#selfie: Selfie) { let selfieImageURL:NSURL = NSURL(string: selfie.show_selfie_pic())! self.selfieImageView.hnk_setImageFromURL(selfieImageURL, placeholder: nil, format: HNKFormat<UIImage>(name: "original"), failure: {error -> Void in println(error) }, success: { (image) -> Void in // Screen Width var screen_width = UIScreen.mainScreen().bounds.width // Ratio Width / Height var ratio = image.size.height / image.size.width // Calculated Height for the picture let newHeight = screen_width * ratio // METHOD 1 self.heightConstraint.constant = newHeight // METHOD 2 //self.selfieImageView.bounds = CGRectMake(0,0,screen_width,newHeight) self.selfieImageView.image = image } ) } 

}

 override func viewDidLoad() { super.viewDidLoad() // Register the xib for the Custom TableViewCell var nib = UINib(nibName: "TestCell", bundle: nil) self.tableView.registerNib(nib, forCellReuseIdentifier: "TestCell") // Set the height of a cell dynamically self.tableView.rowHeight = UITableViewAutomaticDimension self.tableView.estimatedRowHeight = 500.0 // Remove separator line from UITableView self.tableView.separatorStyle = UITableViewCellSeparatorStyle.None loadData() } override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { var cell = tableView.dequeueReusableCellWithIdentifier("TestCell") as TestCellVC cell.loadItem(selfie: self.selfies_array[indexPath.row]) // Remove the inset for cell separator cell.layoutMargins = UIEdgeInsetsZero cell.separatorInset = UIEdgeInsetsZero // Update Cell Constraints cell.setNeedsUpdateConstraints() cell.updateConstraintsIfNeeded() cell.sizeToFit() return cell } 

Mi cálculo de la altura dinámica es correcto (lo he impreso). He intentado ambos methods (describir en el código), pero ninguno de ellos funcionó:

  1. Establezca la restricción Height Autolayout de UIImageView
  2. Modifique el marco de UIImageView

Vea aquí los Resultados del Método 1 y 2: imagenImagen 2

Por favor, ayúdame !! Gracias por adelantado.

En el guión gráfico, agregue las restricciones arrastradas, principales, inferiores y superiores a su UIImageView . Después de cargar su image todo lo que necesita hacer es agregar una restricción de aspecto a su UIImageView . Su celda de imágenes se vería así:

 class ImageTableViewCell: UITableViewCell { @IBOutlet weak var customImageView: UIImageView! internal var aspectConstraint : NSLayoutConstraint? { didSet { if oldValue != nil { customImageView.removeConstraint(oldValue!) } if aspectConstraint != nil { customImageView.addConstraint(aspectConstraint!) } } } override func prepareForReuse() { super.prepareForReuse() aspectConstraint = nil } func setCustomImage(image : UIImage) { let aspect = image.size.width / image.size.height let constraint = NSLayoutConstraint(item: customImageView, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: customImageView, attribute: NSLayoutAttribute.height, multiplier: aspect, constant: 0.0) constraint.priority = 999 aspectConstraint = constraint customImageView.image = image } } 

Puede consultar el ejemplo de trabajo aquí DynamicTableWithImages

Si desea que UIImageView le diga a UITableView qué tan alto debe ser, entonces debe configurar la vista de tabla para habilitar el cálculo automático de filas. Para ello, configure estimatedRowHeight en un valor positivo fijo y establezca rowHeight en UIViewAutomaticDimension. Eso es parte uno.

Ahora necesita configurar el UIImageView para solicitar una altura basada en el ancho que requiere la vista de tabla y en la relación de aspecto de la image. Esta será la segunda parte.

Primero, establezca contentMode en .AspectFit. Esto hará que la vista cambie el tamaño de la apariencia de la image en function de las dimensiones que tome. Sin embargo, esto todavía no hace que solicite la altura necesaria con layout automático. En su lugar, solicitará la altura del Contenido intrínseco, que puede ser bastante diferente de la image networkingimensionada. Entonces, en segundo lugar, agregue una restricción al UIImageView que es del width = height * multiplier , donde el multiplicador se basa en la relación de aspecto de la image misma.

Ahora la vista de la tabla requerirá el ancho correcto, el mecanismo contentMode garantizará que la image se networkingimensiona correctamente sin distorsión, y la restricción de la relación de aspecto asegurará que la vista de la image requiera la altura correcta a través de la disposition automática.

Esto funciona. La desventaja es que necesitará actualizar la restricción de la relación de aspecto cada vez que asigne una nueva image a la vista de la image, lo que podría ser muy a menudo si la vista de la image se encuentra en una celda que se está reutilizando.

Un enfoque alternativo es agregar solo una restricción de altura y actualizarlo en las vistas de layout de una vista que contiene la vista de la image. Esto tiene un mejor performance, pero peor modularidad de código.

Elimine la restricción de altura de su imageView. Elija el modo de contenido de la vista de image que comienza con "aspecto", por ejemplo: relleno de aspecto o ajuste de aspecto (según se ajuste a sus requisitos).

NOTA : También debe establecer el alto de la fila para que la image se ajuste a ella. Utilizar

 heightForRowAtIndexPath 

para establecer la altura de fila personalizada.