Implementing the compact size layout

To implement the compact size layout, you'll combine VFL and anchors. Anchors are fairly straightforward; the best way for you to understand how they work is by using them.

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 you must set these variables before attempting to use them. If you fail to do this,  the app will crash due to an unexpected nil value.

You often want to avoid implicitly unwrapping optionals. Using optionals without implicit unwrapping enforces safety because you need to unwrap these values before attempting to use them. However, in some cases, you want your program to crash if a value isn't set; for instance, when there's no sensible way to recover from such a missing value. Scenarios like these are very rare, and you should use implicit unwrapping with great caution. In this example, it's used for brevity.

The following code should be added to the viewDidLoad method:

// 1
let views: [String: Any] = ["contactImage": contactImage, "contactNameLabel": contactNameLabel]

var allConstraints = [NSLayoutConstraint]()

// 2
compactWidthConstraint = contactImage.widthAnchor.constraint(equalToConstant: 60)
compactHeightConstraint = contactImage.heightAnchor.constraint(equalToConstant: 60)

// 3
let verticalPositioningConstraints = NSLayoutConstraint.constraints(
  withVisualFormat: "V:|-[contactImage]-[contactNameLabel]",
  options: [.alignAllCenterX], metrics: nil, views: views)

allConstraints += verticalPositioningConstraints

// 4
let centerXConstraint = contactImage.centerXAnchor.constraint(equalTo: self.view.centerXAnchor)

// 5
allConstraints.append(centerXConstraint)
allConstraints.append(compactWidthConstraint)
allConstraints.append(compactHeightConstraint)

//6
NSLayoutConstraint.activate(allConstraints)

There is a lot going on in the preceding snippet so take some time to study it closely. First, a dictionary of views is created. This dictionary is used by VFL later in step 3 to figure out which views correspond to the views mentioned in the format string. In step 2, the width and height for the image view are being set up. These constraints are configured with anchors. Every attribute that you can use for constraints can be represented with an anchor, in this case, width and height anchor, but there are also left, right, top, and bottom anchors that you can use to specify a layout with. Step 3 defines a visual format string to define the spacing between the contactImage object and the contactNameLabel object. By passing .alignAllCenterX to the options list for this format string, all views that participate in this string are aligned horizontally. Step 4 defines a constraint that places the image view in the middle of the view controller's view. Step 5 adds all anchor constraints to the allConstraints array. The final step is to call NSLayoutConstraint.activate(_:) to activate all constraints in the allConstraints array.

Try running your app on a device with a small screen; your layout should look just like it did before. The next step is to adapt this layout to larger screens by implementing the regular size layout.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset