Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
An image view that can computes its intrinsic height from its width while preserving aspect ratio
import UIKit
/// An image view that computes its intrinsic height from its width while preserving aspect ratio
/// Source: https://stackoverflow.com/a/48476446
class ScaledHeightImageView: UIImageView {
// Track the width that the intrinsic size was computed for,
// to invalidate the intrinsic size when needed
private var layoutedWidth: CGFloat = 0
override var intrinsicContentSize: CGSize {
layoutedWidth = bounds.width
if let image = self.image {
let viewWidth = bounds.width
let ratio = viewWidth / image.size.width
return CGSize(width: viewWidth, height: image.size.height * ratio)
}
return super.intrinsicContentSize
}
override func layoutSubviews() {
super.layoutSubviews()
if layoutedWidth != bounds.width {
invalidateIntrinsicContentSize()
}
}
}
@pepasflo

This comment has been minimized.

Copy link

commented Aug 7, 2019

Thanks so much!

Here's a slightly refactored version:

/// An image view that computes its intrinsic height from its width while preserving aspect ratio
// Based on https://gist.github.com/marcc-orange/e309d86275e301466d1eecc8e400ad00
public class DerivedHeightImageView: UIImageView {

    public override var intrinsicContentSize: CGSize {
        previousLayoutWidth = bounds.width

        guard let image = self.image else {
            return super.intrinsicContentSize
        }

        return CGSize(
            width: bounds.width,
            height: bounds.width / image.size.aspectRatio
        )
    }

    public override func layoutSubviews() {
        super.layoutSubviews()
        if previousLayoutWidth != bounds.width {
            invalidateIntrinsicContentSize()
        }
    }

    // Track the width that the intrinsic size was computed for,
    // to invalidate the intrinsic size when needed
    private var previousLayoutWidth: CGFloat = 0
}

extension CGSize {
    public var aspectRatio: CGFloat {
        return width / height
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.