In Xcode 5, Apple introduced a new system for building application interfaces for iOS (6+) and MAC OS X (v10.7 +) “Auto Layout” (AL) designed to replace the outdated “Springs & Struts” (S & S). Based on the specification of rules (Constraints) that determine the size and position of the interface elements, AL provides significantly more opportunities than S & S. However, the weak side of AL (apart from its greater complexity) is the work with variable sets of elements. The AL system itself does not support optional elements at all, but there are ways to get around this limitation.
Suppose we need to show cards of cat breeds, each card will contain the name of the breed, the country of origin and a short description. Create a new xib file for our card, add three labels to the root view (remember to set the lines = 0 property) and set the necessary constraints:
Add a few of these cards in ScrollView:
Here we have no optional elements and everything looks as it should, but what will happen if we do not have enough information? For example, we do not know the country of origin or the description is missing?
')
Obviously, the dimensions of the labels for the missing data became zero, and the indents at the top and bottom just folded. This problem can be solved in several ways:
Method one: remove unused items from the view when filling in the data. Along with the removal of an element of the interface, all associated constraints are also removed. True, if you simply remove, for example, the label of the country of origin of the population, the indent between the name and description will not be determined. Therefore, you must first add additional constraints for the cases of deleting each of the optional elements:



Now, when filling in the data, it is enough to call the method for empty labels.
- (void)removeFromSuperview
and cards will be formed correctly:
There are two drawbacks to this approach:
- It is required to introduce a lot of additional constraints (and their number will grow with an increase in the number of optional elements)
- Since the labels are removed, the once filled card cannot be reused, because There is no guarantee that the data sets will match. At first glance, this may seem insignificant, because you can always create a new card. But, if we need to show our cards not in ScrollView, but in CollectionView that implements the “Object Pool” pattern, the cards should be reusable.
To avoid these shortcomings, we will have to revise the structure of our card:
- Above and below we will add two views of a fixed height. They will serve to set indents from the edges.
- We enclose each label in view.
Add constraints:
Moreover, for constraint'ov inside the blocks (marked with a dotted line) set the priority value equal to 750 (High)
Now we only need to add constraints for heights:
Method two: set the height of the blocks with content . Changing the values of X, Y, Z, you can limit the maximum height of each block, so when filling a card in the absence of content, set the block height to 0, and if the content is, then any value that exceeds the maximum block height.
Thus, we avoided all the shortcomings of the previous method: the number of required constraints does not increase in proportion to the number of optional elements and the card can be reused.
Findings:
If reuse is not required and the number of optional elements is small, it is better to add additional constraints and remove unnecessary elements when filling in the data. In the case when either reuse is required, or a lot of optional elements it is worth splitting the interface into blocks and for height of empty blocks set the height to 0.