Intrinsic Content Size
With Auto Layout, a view’s content plays as important a role in its layout as its constraints. This is expressed through each view’s intrinsicContentSize, which describes the minimum space needed to express the full view content without squeezing or clipping that data. It derives from the natural properties of the content that each view presents.
For an image view, for example, the intrinsic content size corresponds to the size of the image it presents. A larger image requires a larger intrinsic content size. Consider the following code snippet. It loads an iOS 7 standard Icon.png image into an image view and reports the view’s intrinsic content size. As you’d expect, this size is 60 by 60 points, the size of the image supplied to the view (see Figure 1-7, top):
Figure 1-7 A view’s intrinsic content size is the natural size that its contents occupy.
UIImageView *iv = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Icon-60.png"]]; NSLog(@"%@", NSStringFromCGSize(iv.intrinsicContentSize));
For a button, the intrinsic content size varies with its title (see the button images in Figure 1-7). As a title grows or shrinks, the button’s intrinsic content size adjusts to match. This snippet creates a button and assigns it a pair of titles, and it reports the intrinsic content size after each assignment:
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem]; // Longer title, Figure 1-7, middle image [button setTitle:@"Hello World" forState:UIControlStateNormal]; NSLog(@"%@: %@", [button titleForState:UIControlStateNormal], NSStringFromCGSize(button.intrinsicContentSize)); // Shorter title, Figure 1-7, bottom image [button setTitle:@"On" forState:UIControlStateNormal]; NSLog(@"%@: %@", [button titleForState:UIControlStateNormal], NSStringFromCGSize(button.intrinsicContentSize));
When run, this snippet outputs the following sizes:
2013-07-02 12:16:46.576 HelloWorld[69749:a0b] Hello World: {78, 30} 2013-07-02 12:16:46.577 HelloWorld[69749:a0b] On: {30, 30}
The Hello World version of the button expresses a wider intrinsic content size than the On version, and both use the same height. These values can vary further as you customize a font face and font size and title text.
A view’s intrinsic size allows Auto Layout to best match a view’s frame to its natural content. Earlier, you read that unambiguous layout generally requires setting two attributes in each axis. When a view has an intrinsic content size, that size accounts for one of the two attributes. You can, for example, place a text-based control or an image view in the center of its superview, and its layout will not be ambiguous. The intrinsic content size plus the location combine for a fully specified placement.
When you change a view’s intrinsic contents, you need to call invalidateIntrinsicContentSize to let Auto Layout know to recalculate at its next layout pass.