Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

Replaced occurrences of OS X with macOS

  • Loading branch information...
justin committed Jul 16, 2016
1 parent 41b0ea2 commit 4608c5a1c05a275cd046dfdaeeb1fd53893dbb9c
@@ -1,7 +1,7 @@
Chapter 01 - Introduction
====================================

We’ve all been there. Apple announces an all-new technology at their annual Worldwide Developers Conference. It’s designed to replace something that you’ve been using since you started down the road as an OS X or iOS programmer. The demos in the session look great. You can’t wait to get home and try this new stuff out!
We’ve all been there. Apple announces an all-new technology at their annual Worldwide Developers Conference. It’s designed to replace something that you’ve been using since you started down the road as an macOS or iOS programmer. The demos in the session look great. You can’t wait to get home and try this new stuff out!

And then you get home and realize, “Oh, this isn’t as easy as I thought.”
As software developers, we’re used to adapting to a learning curve whenever we try to implement a new technology in our products; it’s just part of the job. Unfortunately, some technologies have a steeper curve than others. One of the technologies that has had the biggest learning curve over the last few years is Auto Layout.
@@ -18,13 +18,13 @@ If you haven’t even started using Auto Layout yet, but Apple’s announcements

### Prerequisites

This book presumes that you are a seasoned OS X or iOS developer using Objective-C or Swift. If this is the first time you’ve ever heard the words Objective-C or Swift, you might want to start with another book that teaches you the fundamentals. These are books and authors I recommend:
This book presumes that you are a seasoned macOS or iOS developer using Objective-C or Swift. If this is the first time you’ve ever heard the words Objective-C or Swift, you might want to start with another book that teaches you the fundamentals. These are books and authors I recommend:

* [iOS Programming: The Big Nerd Ranch Guide][bnr]
* [Cocoa Programming for OS X][osx]
* [Cocoa Programming for macOS][osx]
* [Programming iOS 8][oreilly]

I’m also going to make the assumption that you are targeting at least iOS 9 or OS X El Capitan with your products and are using the latest version of Xcode 7.0 and Swift 2.0, where appropriate. I’ll do my best to point out some tricks that can help with backwards compatibility to previous operating system releases.
I’m also going to make the assumption that you are targeting at least iOS 9 or macOS El Capitan with your products and are using the latest version of Xcode 7.0 and Swift 2.0, where appropriate. I’ll do my best to point out some tricks that can help with backwards compatibility to previous operating system releases.

### Organization of This Book

@@ -42,7 +42,7 @@ I don’t believe that’s the best way to tackle a singular technology like Aut

Throughout the book there are several snippets of code explaining how to accomplish different tasks using Auto Layout. Where appropriate, I am also providing a sample Xcode project or Playground that fully implements the feature. You should have received a ZIP file of these samples when you made your purchase.

All of the code samples were written using Xcode 7 and targeted towards OS X El Capitan and iOS 9 respectively.
All of the code samples were written using Xcode 7 and targeted towards macOS El Capitan and iOS 9 respectively.

### Errata and Issues

@@ -21,11 +21,11 @@ Let's look at a basic example. Let's say that you have a `UILabel` that you want

Auto Layout is about explicitly defining these relationships either in code or with Interface Builder using constraints. A **constraint** is a way to describe the relationship between two views. A constraint can describe things such as the height or width of the view, how far from another view it should be, how to center it, etc. Once you pass these constraints to the Auto Layout engine, it can then go ahead and work its magic.

Auto Layout was introduced in OS X Lion and iOS 6, so it has a few years under its belt thus far. It has been enhanced in subsequent releases of OS X—both at the code and Interface Builder levels—allowing it to handle layouts as basic or as complex as you want to throw at it.
Auto Layout was introduced in macOS Lion and iOS 6, so it has a few years under its belt thus far. It has been enhanced in subsequent releases of macOS—both at the code and Interface Builder levels—allowing it to handle layouts as basic or as complex as you want to throw at it.

### Dynamic vs. Absolute Layout

The present-day OS X and iOS operating systems are both based off that NeXTSTEP OS. The Interface Builder you use now has existed in some form since the NeXTSTEP days, although you may not easily recognize it up against the modern Xcode 7 incarnation.
The present-day macOS and iOS operating systems are both based off that NeXTSTEP OS. The Interface Builder you use now has existed in some form since the NeXTSTEP days, although you may not easily recognize it up against the modern Xcode 7 incarnation.

One of the key features of the Interface Builder paradigm is the concept of Springs & Struts. Springs & Struts allow a developer to easily handle a variety of different layout situations in a static manner. Interface Builder allows you to set specific springs and struts to define how a view or window should resize when faced with the task.

@@ -128,7 +128,7 @@ It's not that the traditional absolute layout system was bad necessarily, but th

![Interface Builder](./images/ch02-ss04.png)

Interface Builder is no doubt part of the secret sauce that makes building apps for OS X and iOS so enjoyable. Rather than being knee-deep in XML layouts or writing a bunch of boilerplate code to create a table view, you can instead drag the table view onto its parent view and set up a majority of its visual attributes.
Interface Builder is no doubt part of the secret sauce that makes building apps for macOS and iOS so enjoyable. Rather than being knee-deep in XML layouts or writing a bunch of boilerplate code to create a table view, you can instead drag the table view onto its parent view and set up a majority of its visual attributes.

Auto Layout extends the power of Interface Builder by allowing you to define the constraint-based relationships each of your views have visually.

@@ -212,7 +212,7 @@ The good news is that Xcode 5's support for Auto Layout was vastly superior to i

#### Steep Learning Curve

Above all else, the Auto Layout system has a steep learning curve because it changes such a fundamental aspect of OS X and iOS development. You're no longer doing manual frame calculations and are instead writing these strange ASCII-Art formatted strings or working with an `NSLayoutConstraint` class method with 7 parameters to keep track of. With iOS 9, Apple has done some work to improve the verbosity of Auto Layout, but the core concepts under the hood remain the same.
Above all else, the Auto Layout system has a steep learning curve because it changes such a fundamental aspect of macOS and iOS development. You're no longer doing manual frame calculations and are instead writing these strange ASCII-Art formatted strings or working with an `NSLayoutConstraint` class method with 7 parameters to keep track of. With iOS 9, Apple has done some work to improve the verbosity of Auto Layout, but the core concepts under the hood remain the same.

I won't deny that the learning curve is steep, but once everything begins to click, the rewards more than pay off for the early frustration. I only truly embraced and adopted Auto Layout when I forced myself to use it for a major project and refused to fall back on my old knowledge and habits.

@@ -143,7 +143,7 @@ If the intrinsic content size defines the size of the content that we want to la

An alignment rectangle is useful if you're working with a view that has extra ornamentation, such as a badge on a button that you don't necessarily want to take into account when laying out the control.

In the case of a badged button, you can just override `alignmentRectInsets` in its subclass to return either a `UIEdgeInsets` (iOS) or `NSEdgeInsets` (OS X) to define the alignment rectangle.
In the case of a badged button, you can just override `alignmentRectInsets` in its subclass to return either a `UIEdgeInsets` (iOS) or `NSEdgeInsets` (macOS) to define the alignment rectangle.

If you need to do something more complex than insetting the full-frame of a view, you can override `frameForAlignmentRect:` to define an actual CGRect or NSRect, depending on which OS you are targeting. UIImage also has a method, `imageWithAlignmentRectInsets`, which you can override to return a new version of the image adjusted by those insets.

@@ -46,7 +46,7 @@ You can trigger a measurement pass by calling `setNeedsUpdateConstraints()`, whi

### Laying Out Views

Once Auto Layout has taken a measurement pass and calculated the values we should have for each of our views, it can go through the actual process of setting those values against the views. For old hands of iOS and OS X development, this is basically an automated way of calling `setFrame()`. The Auto Layout engine calculates those frame values and then simply iterates through our views—from superview down to subview—calling `setFrame:` on each of them.
Once Auto Layout has taken a measurement pass and calculated the values we should have for each of our views, it can go through the actual process of setting those values against the views. For old hands of iOS and macOS development, this is basically an automated way of calling `setFrame()`. The Auto Layout engine calculates those frame values and then simply iterates through our views—from superview down to subview—calling `setFrame:` on each of them.

If you've elected to use Auto Layout but are still calling `setFrame()` manually, you've likely had the headache of debugging why your view doesn't look exactly like you expect. This is why. **If you're using Auto Layout, you should never call `setFrame()` yourself.** Trust the `NSISEngine` (the private class doing all the layout calculation and management) to do the heavy lifting for you.

@@ -60,7 +60,7 @@ It should be noted that each step in the Auto Layout process is iterative, so ev

The final step of the Auto Layout process is the one you are likely most familiar with: actually drawing on screen. We've solved our constraint equations and set our frames to match those values. Now, we actually need to render this all on-screen for our user to interact with.

The drawing process operates from the top down, superview to subview, and actually paints our views on-screen using layoutSubviews() on iOS and layout() on OS X. Here, the system is copying the subview frames that were calculated from the layout engine and applying them to each view in your UI one-by-one.
The drawing process operates from the top down, superview to subview, and actually paints our views on-screen using layoutSubviews() on iOS and layout() on macOS. Here, the system is copying the subview frames that were calculated from the layout engine and applying them to each view in your UI one-by-one.

You can trigger this step by calling `setNeedsDisplay()`, which notifies the system that you would like the specific view to be redrawn during the next drawing cycle.

@@ -10,7 +10,7 @@ The first part of our journey into Auto Layout was focused on understanding some

**If you are using Auto Layout, you should be using Interface Builder.** This is one of the most declarative statements I will make in this book, but that's because I am passionate about it.

Interface Builder has always been a great way to lay out your interface, providing a high-level visual overview of what your UI will look like on a user's OS X desktop or iOS device. Rather than requiring you to manage big chunks of tedious layout code, Interface Builder instead does all the heavy loading and lets you focus on the important functionality of your application.
Interface Builder has always been a great way to lay out your interface, providing a high-level visual overview of what your UI will look like on a user's macOS desktop or iOS device. Rather than requiring you to manage big chunks of tedious layout code, Interface Builder instead does all the heavy loading and lets you focus on the important functionality of your application.

One of the key reasons Auto Layout exists is to extend the usefulness of Interface Builder, and with Xcode 7, that usefulness is even more powerful. Each release of Xcode since version 4 has improved on the Auto Layout support in Interface Builder; as amateur Apple watchers, this should be a pretty obvious sign that Apple thinks this is important technology.

@@ -38,7 +38,7 @@ To get started, open Xcode and create a new Single View Application project. Nam

![Single View Project](./images/ch05-ss04.png)

Once we save DeveloperTown to disk, we are shown a skeleton project with an app delegate, starter view controller, and storyboard. Storyboards are Apple's preferred way of laying out high level interfaces on both iOS and OS X, so let's go ahead and keep that rather than using separate XIB files for our view controllers.
Once we save DeveloperTown to disk, we are shown a skeleton project with an app delegate, starter view controller, and storyboard. Storyboards are Apple's preferred way of laying out high level interfaces on both iOS and macOS, so let's go ahead and keep that rather than using separate XIB files for our view controllers.

Open _Main.storyboard_, and you'll be presented with an empty square that defines our view controller's scene. If you're a seasoned iOS developer but haven't been working with iOS 8 or newer, this likely looks a little foreign. This is Apple's new concept of **size classes**.

@@ -250,7 +250,7 @@ We have our image view back on screen and exactly where we wanted it!

One view down, five to go.

Next, we will focus on the relationship between our labels and the text fields. In our view, you'll notice that we have the left (or leading) edge of the labels lined up with the left edge of our text fields. When working with text, you want to use leading and trailing constraints. By doing this, iOS and OS X are able to account for left-to-right languages when rendering your views on screen.
Next, we will focus on the relationship between our labels and the text fields. In our view, you'll notice that we have the left (or leading) edge of the labels lined up with the left edge of our text fields. When working with text, you want to use leading and trailing constraints. By doing this, iOS and macOS are able to account for left-to-right languages when rendering your views on screen.

Let's go ahead and make a few explicit constraints to define those relationships.

@@ -279,11 +279,11 @@ Next let's define our constraints for the e-mail address and password text field

### Layout Anchors

You will no doubt have nightmares about the verbosity of creating constraints using the `NSLayoutConstraint` initializer method. As of iOS 9 and OS X El Capitan, however, there is a better way that can get around that repetitiveness. Apple added a new feature to views called layout anchors.
You will no doubt have nightmares about the verbosity of creating constraints using the `NSLayoutConstraint` initializer method. As of iOS 9 and macOS El Capitan, however, there is a better way that can get around that repetitiveness. Apple added a new feature to views called layout anchors.

All of the magic of layout anchors is provided by the `NSLayoutAnchor` class, which handles the work of creating individual `NSLayoutConstraint` objects under the hood. Using layout anchors to generate your constraints also provides you an additional piece of type-checking in that it won't allow you to create an invalid constraint—such as constraining the top edge of a view to another attribute in a view that's not in the same hierarchy. If you try to do so, you'll get a compile error.

You shouldn't ever need to interact directly with the `NSLayoutAnchor` class. Both `UIView` on iOS and `NSView` on OS X provide an instance that you can work directly with. Let's see how this works by defining five new constraints for our e-mail address text field and label.
You shouldn't ever need to interact directly with the `NSLayoutAnchor` class. Both `UIView` on iOS and `NSView` on macOS provide an instance that you can work directly with. Let's see how this works by defining five new constraints for our e-mail address text field and label.

1. The e-mail address text field should be horizontally centered in its parent view.
2. The e-mail address label's leading edge should equal the leading edge of the e-mail address text field.
@@ -365,7 +365,7 @@ What's going on here? First we are defining a dictionary with value references t

The main line we want to focus on is the `verticalLogoConstraints` variable. We are using a new (to us) method on `NSLayoutConstraint` called `constraintsWithVisualFormat()` that returns an array of constraints. The first parameter of `constraintsWithVisualFormat()` defines the constraints we are going to be creating. There are a few things to point out here.

First, you'll notice the first portion of the constraint definition is "V:". What this is telling Auto Layout is that we are wanting to define constraints on the vertical axis. If we wanted to work with the horizontal axis, we'd use "H:" instead. Next you see a reference to our "logo" key from the `views` dictionary, wrapped inside square brackets. There's also "emailLabel" wrapped in square brackets. Between those two views is a single hyphen "-". The hyphen tells Auto Layout that you want to have the standard amount of space between those two views on our vertical axis. The standard amount of space is defined and managed by iOS and OS X respectively.
First, you'll notice the first portion of the constraint definition is "V:". What this is telling Auto Layout is that we are wanting to define constraints on the vertical axis. If we wanted to work with the horizontal axis, we'd use "H:" instead. Next you see a reference to our "logo" key from the `views` dictionary, wrapped inside square brackets. There's also "emailLabel" wrapped in square brackets. Between those two views is a single hyphen "-". The hyphen tells Auto Layout that you want to have the standard amount of space between those two views on our vertical axis. The standard amount of space is defined and managed by iOS and macOS respectively.

If you wanted to define a different amount of space between the logo and emailField, you could replace the hyphen with something like `V:[logo]-10-[emailLabel]`, which would add ten points of padding between the two controls on the vertical axis.

@@ -421,7 +421,7 @@ Now if we run our application, we can see that everything is laid out exactly ho

### Summary

In this chapter, we looked at recreating our sign-in screen using Auto Layout constraints defined in code rather than Interface Builder. We started by holding strong references to individual constraints, so we can adjust their constant values or activated status on the fly. We followed up by defining individual `NSLayoutConstraint` instances. We then simplified things using the new layout anchors feature in iOS 9 and OS X El Capitan. Finally, we covered the visual format language that allows us to easily define multiple constraints in a single line.
In this chapter, we looked at recreating our sign-in screen using Auto Layout constraints defined in code rather than Interface Builder. We started by holding strong references to individual constraints, so we can adjust their constant values or activated status on the fly. We followed up by defining individual `NSLayoutConstraint` instances. We then simplified things using the new layout anchors feature in iOS 9 and macOS El Capitan. Finally, we covered the visual format language that allows us to easily define multiple constraints in a single line.

In the next chapter, we are going to cover a few more advanced code-based uses of Auto Layout: layout guides and margins.

0 comments on commit 4608c5a

Please sign in to comment.
You can’t perform that action at this time.