To implement the compact size layout, we'll use VFL and anchors. Anchors are fairly straightforward, so let's have a look at the implementation right away and discuss them later.
First, add the following two variables that will be used later to activate and deactivate the compact size constraints:
var compactWidthConstraint: NSLayoutConstraint!
var compactHeightConstraint: NSLayoutConstraint!
These variables will be set in viewDidLoad, and we're using implicitly unwrapped optionals for them. This means that we must set these variables before attempting to use them, otherwise the app will crash due to an unexpected nil value.
The following code should be added to the viewDidLoad method:
let views: [String: Any] = ["contactImage": contactImage,
"contactNameLabel": contactNameLabel]
var allConstraints = [NSLayoutConstraint]()
compactWidthConstraint = contactImage.widthAnchor.constraint(equalToConstant: 60)
compactHeightConstraint = contactImage.heightAnchor.constraint(equalToConstant: 60)
let verticalPositioningConstraints = NSLayoutConstraint.constraints(
withVisualFormat: "V:|-[contactImage]-[contactNameLabel]",
options: [NSLayoutFormatOptions.alignAllCenterX],
metrics: nil,
views: views)
allConstraints += verticalPositioningConstraints
let centerXConstraint = contactImage.centerXAnchor.constraint(
equalTo: self.view.centerXAnchor)
allConstraints.append(centerXConstraint)
allConstraints.append(compactWidthConstraint)
allConstraints.append(compactHeightConstraint) NSLayoutConstraint.activate(allConstraints)
In the preceding code snippet, we created a dictionary of views, which is used later in VFL. We will also instantiate an empty array of constraints. This array will be used to activate all the constraints at once. The following lines assign values to the variables you added before adding this code snippet. These lines make use of the anchor technique to add constraints. You'll notice that the syntax is fairly straightforward. The constraint method is called on the anchor we wish to use, and the desired value is passed as an argument.
The vertical positioning is defined in VFL. A string is passed that vertically aligns the views with standard spacing. There's also an option passed to align all views involved on the x axis so they're centered, and finally the views dictionary is passed in. This dictionary is used to map the string values in the format string to the views we want to lay out. The resulting constraints are then merged with the allConstraints array.
Next, the contact image is aligned to the main view's x axis by using the anchor technique again. Finally, the three constraints that were created using anchors are added to the list of constraints and all of the constraints get activated at once. If you test your app on an iPhone now, everything should work out as expected.