So I Wanted To Get The Height Of A UIImage
What, What You Say?
Have you ever wanted to get the size of a UIImage
contained within a UIImageView
? It’s quite easy really, just use the following line of code:
let size = imageView.image?.size ?? .zero // optional for brevity
However, if you happen to’ve set a contentMode
such as .scaleAspectFill
on your UIImageView
, the size returned upon calling the getter will not be the view’s bounds — it will be the size of the actual image. This can be anywhere between zero and a few trillion gigapixels in size, or however big the image was, which revealed the M87 Black Hole.
Sidebar: Could an iOS device in this day and age render such an image?
Scenario
Given that you download an image from a URL, and set it on a UIImageView
with content mode .scaleAspectFill
, which is embedded inside a UICollectionViewCell
of size CGSize(width: 50, height: 50)
, it would be ideal if we could find the relative size of the image, after the “scale” has been applied, rather than returning a potential image size equal to that of the planet Saturn.
Baby, Baby Can’t You See? I’ve Got Everything You Need
Much better! I divided the functions between each other, to make the Math clear for the purposes of demonstration. But you could probably adjust it to wind up with one computed variable which covers all four conditions.
Dot The I’s And Cross The T’s
- Given a
UICollectionViewCell
of sizeCGSize(width: 100, height: 250)
- It has a
UIImageView
of sizeCGSize(width: 100, height: 100)
and takes an image downloaded from a URL, and the content mode is.scaleAspectFill
. - Once the image has been set, we want to calculate the relative, scaled down height of the image based on the width. The math for this is standard aspect ratio calculation.
- Given a
bounds
width of100
, we divide100
by the accessible size of the image itself, which, in my example is750x750px
.100 / 750 == 0.1333333333
. Since my image view frame is square, the same applies for the height calculation. - The width and height are now computable by multiplying the
relativeWidth
by theimage.size.height
and therelativeHeight
by theimage.size.width
. - New width value:
0.1333333333 * 750 == 99.999999975
or100
, as you expect. The height is also the same in this case. - Disclaimer: The values will differ if the image holds an aspect ratio other than
1:1
! - I don’t calculate the scaled size for other content modes, because when you use those, the image is set to its actual size, and positioned left/right/top/bottom etcetera.
- I use
ceil
because I want whole numbers. - I also use
traitCollections
well, because you should be anyway but if it’s not, it falls back toUIScreen
scale.
Conclusion
You may wonder why in fact that I use an extension as opposed to a separate utility class which could very easily do this for me. Everything is relative! You can use whichever approach you choose, and in this case I chose a common one, which is one that even beginner Swift engineers can make use of.
You do however, need to err on the side of caution with extensions. Wherever possible, you should restrictively extend whatever it is, in order to only apply the extension where you want it. It can be easy to extend something you don’t mean to. If you pick out that there’s a risk of that happening, go the utility class route!
If you liked this post, consider giving me a clap, or seven. このストーリーを好きなら、拍手ボタンを長く押して頂けないでしょうか。w