I have received a bug. The bug is a bit of a head scratcher because it’s one of those bugs you swear should not have happened. We checked for these exact conditions several times and it was fine. But here I am a month later wondering what happened. The problem: a view in our iOS application is not consuming all remaining space in it’s parent view. Time for me to double down on my knowledge of iOS views to figure out what is going on.

Apple’s Guidance

I only have a hunch, however I believe this may be a result of the content hugging and compression constraints. This is probably because I am not really familiar with what these are and how they work. The first Apple hit on Google leads to a bunch fo places. There is a reference to another article where they define what intrinsic content size, content hugging, and compression resistance.

The intrinsic content size is dependent upon the contents of the particular view. For example the size of a label is based on the font size for height and length of the text for the width as rendered in the font. An image view only has a size when the image is loaded into the components. This makes sense, I am hoping a UIView will propagate the size the components the view contains. A component must have an intrinsic content size for compression resistance or content hugging to have any effect.

Content hugging describes the weight a view has towards expanding to consume the available space. If a view with a intrinsic horizontal size has a high priority I believe it will consume more space in the auto-layout phase. This term feels a bit opposite of what it should be.

Compression Resistance on the other hand describes how the intrinsic horizontal size will shrink when insufficient space is available. From my current understanding it’s weighted across all available space. With ties being broken by the total space available.

Custom UIView auto-layout

Upon investigation of these constraints, I found my actual problem. There is a component intended to provide reusable views. This view instantiates the target custom view from a NIB and attaches it. When looking at the view through the Capture View Heirarchy feature the custom view class was correctly instantiating and consuming the available extra space. However the component view taken from the NIB was not. Turns out you should set autoresizingMask to include .flexibleWidth to get the view to resize.

    contentView.autoresizingMask = .flexibleWidth