Yo tuve el mismo problema. Gracias a todos los que respondieron: pude encontrar una solución usando partes de varias de estas respuestas.
Mi solución es usar swift 5
El problema que estamos tratando de resolver es que podemos tener imágenes con diferentes relaciones de aspecto en nuestro TableViewCell
s, pero queremos que se rendericen con anchos consistentes. Las imágenes deben, por supuesto, renderizarse sin distorsión y llenar todo el espacio. En mi caso, estaba bien con algunos "recortes" de imágenes altas y delgadas, así que usé el modo de contenido.scaleAspectFill
Para hacer esto, creé una subclase personalizada de UITableViewCell
. En mi caso, lo nombré StoryTableViewCell
. Toda la clase se pega a continuación, con comentarios en línea.
Este enfoque funcionó para mí cuando también utilicé una Vista de accesorios personalizada y etiquetas de texto largas. Aquí hay una imagen del resultado final:
Vista de tabla renderizada con ancho de imagen consistente
class StoryTableViewCell: UITableViewCell {
override func layoutSubviews() {
super.layoutSubviews()
// ==== Step 1 ====
// ensure we have an image
guard let imageView = self.imageView else {return}
// create a variable for the desired image width
let desiredWidth:CGFloat = 70;
// get the width of the image currently rendered in the cell
let currentImageWidth = imageView.frame.size.width;
// grab the width of the entire cell's contents, to be used later
let contentWidth = self.contentView.bounds.width
// ==== Step 2 ====
// only update the image's width if the current image width isn't what we want it to be
if (currentImageWidth != desiredWidth) {
//calculate the difference in width
let widthDifference = currentImageWidth - desiredWidth;
// ==== Step 3 ====
// Update the image's frame,
// maintaining it's original x and y values, but with a new width
self.imageView?.frame = CGRect(imageView.frame.origin.x,
imageView.frame.origin.y,
desiredWidth,
imageView.frame.size.height);
// ==== Step 4 ====
// If there is a texst label, we want to move it's x position to
// ensure it isn't overlapping with the image, and that it has proper spacing with the image
if let textLabel = self.textLabel
{
let originalFrame = self.textLabel?.frame
// the new X position for the label is just the original position,
// minus the difference in the image's width
let newX = textLabel.frame.origin.x - widthDifference
self.textLabel?.frame = CGRect(newX,
textLabel.frame.origin.y,
contentWidth - newX,
textLabel.frame.size.height);
print("textLabel info: Original =\(originalFrame!)", "updated=\(self.textLabel!.frame)")
}
// ==== Step 4 ====
// If there is a detail text label, do the same as step 3
if let detailTextLabel = self.detailTextLabel {
let originalFrame = self.detailTextLabel?.frame
let newX = detailTextLabel.frame.origin.x-widthDifference
self.detailTextLabel?.frame = CGRect(x: newX,
y: detailTextLabel.frame.origin.y,
width: contentWidth - newX,
height: detailTextLabel.frame.size.height);
print("detailLabel info: Original =\(originalFrame!)", "updated=\(self.detailTextLabel!.frame)")
}
// ==== Step 5 ====
// Set the image's content modoe to scaleAspectFill so it takes up the entire view, but doesn't get distorted
self.imageView?.contentMode = .scaleAspectFill;
}
}
}
self.imageView.bounds
la imagen estará centrada.