У меня такая же проблема. Спасибо всем, кто ответил - я смог найти решение, используя части нескольких из этих ответов.
Мое решение использует Swift 5
Проблема, которую мы пытаемся решить, заключается в том, что у нас могут быть изображения с разным соотношением сторон в наших TableViewCell
s, но мы хотим, чтобы они отображались с одинаковой шириной. Разумеется, изображения должны отображаться без искажений и заполнять все пространство. В моем случае меня вполне устраивало «обрезка» высоких тонких изображений, поэтому я использовал режим содержимого.scaleAspectFill
Для этого я создал собственный подкласс UITableViewCell
. В моем случае я назвал этоStoryTableViewCell
. Ниже вставлен весь класс со встроенными комментариями.
Этот подход сработал для меня, когда я также использовал настраиваемый вид аксессуаров и длинные текстовые метки. Вот изображение окончательного результата:
Визуализированное табличное представление с постоянной шириной изображения
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
изображение будет по центру.