Auto-Layout: Get UIImageView height to calculate cell height correctly

So I think the underlying issue is a kind of chicken and egg problem.

In order to ‘aspect fit’ the image to the UIImageView the system needs a size for the view, and yet we would like the height of the view to be determined after aspect fitting the image given a known width for the view.

A workaround is to calculate the aspect ratio of the image ourselves and set it as a constraint on the UIImageView when we set the image. That way the auto layout system has enough information to size the view (a width and an aspect ratio).

So I changed your custom cell class to:

class CustomCell: UITableViewCell {

    @IBOutlet weak var imageTitle: UILabel!

    @IBOutlet weak var postedImageView: UIImageView!

    internal var aspectConstraint : NSLayoutConstraint? {
        didSet {
            if oldValue != nil {
                postedImageView.removeConstraint(oldValue!)
            }
            if aspectConstraint != nil {
                postedImageView.addConstraint(aspectConstraint!)
            }
        }
    }

    override func prepareForReuse() {
        super.prepareForReuse()
        aspectConstraint = nil
    }

    func setPostedImage(image : UIImage) {

        let aspect = image.size.width / image.size.height

        aspectConstraint = NSLayoutConstraint(item: postedImageView, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: postedImageView, attribute: NSLayoutAttribute.Height, multiplier: aspect, constant: 0.0)

        postedImageView.image = image
    }

}

And then in the delegate do this instead of setting the image directly:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as CustomCell

        cell.imageTitle.text = titles[indexPath.row]

        let image = images[titles[indexPath.row]]!
        cell.setPostedImage(image)

        return cell
}

And you will get:

enter image description here

Hope this helps!

Leave a Comment