5
votes

I'm trying to make a UITableView where each cell contains either a portrait or landscape UIImageView, where the images keep their aspect ratio while filling the width of the screen, like this:

|        |
|########|
|########|
|########|
|########|
|########|
|        |
|########|
|########|
|########|
|        |

I've set autolayout constraints to attach the UIImageView's edges to the table view cell's contentView. This works for width, but the height isn't what I want - it always expands to the full height of the underlying image.

I have these settings on the table view:

self.tableView.estimatedRowHeight = 100.0;
self.tableView.rowHeight = UITableViewAutomaticDimension;

When constructing the cell, I'm trying to calculate the necessary height so I can change the frame (or height constraint) of the UIImageView:

let cell = tableView.dequeueReusableCellWithIdentifier("activityPostCell", forIndexPath: indexPath) as UITableViewCell
let image = UIImage(named: "my-image.jpg")
let aspectRatio = image!.size.height / image!.size.width

let imageView = cell.viewWithTag(15) as UIImageView        
let imageViewHeight = aspectRatio * imageView.frame.width

The problem here is that the imageView.frame I get is before layout has occurred, so I'm not computing the correct height anyway.

Am I going about this the right way? Is there an easy way to set a UIImageView's aspect ratio to match the image it contains? Thanks in advance.

1
Have you looked at using an aspect ratio constraint on the image view?Wain
Yes that did the trick, thank you. I'll add my solution as an answer.Michael

1 Answers

7
votes

As per @Wain's suggestion, adding an aspect ratio constraint solved the problem:

let image = UIImage(named: "my-image.jpg")
let aspectRatio = image!.size.height / image!.size.width

let imageView = cell.viewWithTag(15) as UIImageView

imageView.addConstraint(NSLayoutConstraint(
    item: imageView, 
    attribute: NSLayoutAttribute.Height, 
    relatedBy: NSLayoutRelation.Equal, 
    toItem: imageView, 
    attribute: NSLayoutAttribute.Width, 
    multiplier: aspectRatio, 
    constant: 0)
)