5

I have a UIImageView, with scaling Center, so it's size changes according to the UIImage inside, however, by setting a nil UIImage, the constraints break, as no content size can be calculated

How to handle the autolayout with nil UIImage (the size should be changed to 0,0)?

Peter Lapisu
  • 19,915
  • 16
  • 123
  • 179

3 Answers3

18

The problem is that UIImageView returns {-1, -1} as intrinsicContentSize when no image is set. Use subclass of UIImageView with implementation like this:

@implementation MyImageView

- (CGSize)intrinsicContentSize
{
    if (self.image)
    {
        return [super intrinsicContentSize];
    }

    return CGSizeZero;
}

@end
Nikita Ivaniushchenko
  • 1,425
  • 11
  • 11
  • Very helpful, thanks. One minor addition: You might also want to check if the image's size is zero, and in that case, also return `CGSizeZero`, as the default would be {-1, -1}. – hagi Sep 22 '17 at 08:19
13

@nikita-ivaniushchenko's answer gave me an idea to add Width constraint with Low (250) priority equals to 0 to UIImageView, so it is applied when UIImage is set to nil.

Storyboard UIImage Constraints Example

Note: I added Width constraint only, because there was only issue with UIImageView's width in my case. Should work for both, though.

Community
  • 1
  • 1
Yevhen Dubinin
  • 4,657
  • 3
  • 34
  • 57
  • Why should it work? I will try tonight but I'm curious what is behind the answer – Yitzchak Dec 23 '15 at 11:53
  • 1
    I don't know for sure, however, what I suspect, the `intrinsicContentSize` is just some internal constraints, created automatically for our convenience. When we add our height/width constraint, the `intrinsicContentSize`'s constrains either removed or have a lower priority. – Yevhen Dubinin Jan 13 '16 at 16:34
  • @yitschak it worth noting that I gained my assumption based on [this answer](http://stackoverflow.com/a/26353000/1492173) – Yevhen Dubinin Jan 17 '16 at 16:21
  • 1
    It's working for me, just not with 250 but with 500 (or 750). No clue why. – Rick van der Linde Jul 23 '16 at 15:39
  • It also works for me with width = 0, priority > 250. I guess `intrinsicContentSize` has the lowest priority and setting priority to 250 (lowest) let `intrinsicContentSize` to take over. So setting priority anything > 250 just helps. Thanks for this great tip, by the way! – Ayan Sengupta Jul 24 '16 at 21:22
0

Set Content hugging priority to Required (1000).

Update: This answer was working before, but it doesn't work now. Use Nikita Ivaniushchenko answer instead.

Shmidt
  • 16,436
  • 18
  • 88
  • 136
  • just checked once again on iOS 8. When `UIImageView` has `nil` image set, it won't change its size to {0,0}. Consider you have something like this: `|-[imageView]-[label]-|` when there is no image set, the `UIImageView` size will be expanded to maximum available space, no matter what value you set for `Content hugging priority`. It's because when there is no image set in `UIImageView` its `intrinsicContentSize` is {-1,-1} by default. @Nikita Ivaniushchenko answer is a proper solution. – Darrarski Apr 01 '15 at 12:46
  • @Darrarski I created test project and I should say that you're right — at this moment it doesn't work. I have no idea why Apple changed that behaviour recently. – Shmidt Apr 01 '15 at 13:14