Tuesday, 6 May 2014

Measure Twice, Cut Once [There and Back Again]

Like those urban planners, you need a plan. iOS navigation, just like city streets, is difficult to tear up and replace, once built. So begin your design by carefully considering how you want your users to navigate your app. You’llneed to live with your decision, or be willing to expend a fair amount of effort to change it in the future.

iOS navigation can also get complicated. Which is ironic, because the principal player (UIViewController) is a pretty straightforward class. The complication is not in the classes themselves, but in how they combine to formlarger solutions. I think of them like the elements. 

Its not difficult to explain the periodic table—each element has an atomic weight, a number of electrons, and so on.But its quite a different matter to consider all of the ways those elements can combine into molecules andinteract with one another. In this respect, iOS navigation is kind of like chemistry.

So sharpen your No. 2 pencil and get ready to take notes, because you’re about to learn all about navigation: what it means, how its done, the classes involved, and the roles they perform.


What is Navigation?

Every screen in your app is defined, and controlled by, a view controller. If your app has three screens, then it has (at least) three view controllers. The base class for all view controllers is UIViewController.

In its simplest terms, navigation is the transition from one view controller to another. Navigation
is an activity that view controllers participate in, and view controllers are its currency. Now this is where things begin to get interesting. Navigation is not a class, per se, but there are classes that provide specific styles ofnavigation. While view controllers are the subjects of navigation, some view controllers also provide navigation, some only provide navigation, and some non-view controller classes provide navigation. Are you confused yet? Letsbreak it down.


View Controller Roles

View controllers come in two basic varieties. View controllers that just contain view objects are called content view controllers. This is the basic form of view controllers, and what you’ve mostly dealt with in this book so far. Theentire purpose of navigation is to get a content view controller to appear on the screen so the user can see and interact with it.

The other kind is a container view controller. A container view controller presents other view controllers. It may, or may not, have content of its own. Its primary job is to present, and navigate between, a set of view controllers.

The intriguing part is that both content view controllers and container view controllers are both subclasses of UIViewController and are, therefore, all “view controllers.” While a content view controller only displays views, acontainer view controller can present a parade of content view controllers and container view controllers, the latter of which may present other content view controllers or container view controllers, and so on, down therabbit hole.

You wont get confused if you clearly understand the differences, and relationship, between container view controllers and content view controllers. So, lets review. Content view controllers display only tangible view objects.Examples of content view controllers are:

n     UITableViewController

n     UICollectionViewController

n     UIViewController

n     Every custom subclass of UIViewController you’ve created in this book

Note that UIViewController is on that list. The UIViewController base class is a content view controller. It has all of the basic properties and features needed to display a view, and that does not (implicitly) present any views ownedby other view controllers.

Container view controllers present, and provide navigation between, the views in one or more other view controllers. Examples of container view controllers are:

n     UINavigationController

n     UITabBarController

n     UIPageViewController

These view controllers present other view controllers, provide some mechanism for navigating between them, and may decorate the screen with additional view objects that enable that navigation.

So its possible to have a tab bar (container view) controller that contains three other view controllers: a custom (content) view controller, a navigation (container view) controller, and a page (container) view controller. The navigation controller could contain a table (content) view controller. The page view controller could contain a series of custom (content) view controllers, one for each “page.” Does that sound horribly complex? Its not. In fact, its typical of amedium-sized app design, and its exactly the organization of the app you’re about to write. By the end of this chapter, this will seem like childs play.


Designing Wonderland

The app you’re going to write is based on Lewis Carrolls famous book, Alices Adventures in Wonderland. This seems appropriate, given the (sometimes) confounding and convoluted nature of navigation. Heres a summary ofthe screens in your app:

A title page

The full text of the book

Some supplementary information about the author A list of characters
Detailed information about each character

The key is to organize the apps navigation in a way that makes sense, is obvious, is visually appealing, and is easy to use. Think about how you would organize the content of your app while I review the basic styles ofnavigation available.


Weighing Your Navigation Options

To design your app, you need to know what styles of navigation are available, and then what classes and methods provide what you need. Table 12-1 lists the major styles of navigation and the principal class involved.



Table 12-1. Navigation Styles

Style
Class
Description
Modal
UIViewController
One view controller presents a second view controller.When the second view controller is finished, it disappearsand the


first view controller reappears.
Stack or Tree
UINavigationController
View controllers operate in a stack. View controllersmodally present sub-view controllers, adding to the stack,and


navigating deeper into the “tree” of scenes. A navigation bar


at the top takes the user back to the previous view controller,


removing the view controller from the stack, and navigation up


the “tree” towards the root.
Random
UITabBarController
A tab bar appears at the bottom of the screen. The user canjump immediately to any view controller by tapping one of the


buttons in the tab bar.
Sequential
UIPageViewController
The user navigates through a linear sequence of view controllers, moving one view controller at a time, forwards or


backwards.
Concurrent
UISplitViewController
Presents two view controllers simultaneously, eliminatingthe need to navigate between them (iPad only).
Custom
UIViewController  subclass
You decide.

Modal navigation is the simplest, and the one you’ve used the most in this book. When DrumDub presented the MPMediaPicker controller, or MyStuff presented the UIImagePickerController,
these view controllers were presented modally. The new view controller took over the interface
of the device until its task was complete. When it was done, it communicated its results to your controller (via a delegate message), which dismissed the modal controller, and resumed control of the interface. The presentedview controller is responsible for implementing an interface that signals when its done.

n  Use modal navigation when you need to “step out” of the current interface to present 
relevant details, controls, or perform some task and then immediately return the user to 
where they were.


The second style of navigation is the stack or tree style, managed by a UINavigationController object. You see this style all over iOS. The Settings app is a particularly obvious example. The signature of the navigation controller is its navigation bar that appears at the top of the screen. It shows the user where they are, and has a button to return to where they were. When a content view controller (modally) presents a new view controller, the navigation controller adds it to the stack of view controllers the user can step back through. When used in the context of a navigation controller, a view doesnt have to provide a method for returning to the presenting
view controller, because the back button in the navigation bar provides that action.

You can (within strict limits) customize the navigation bar, adding your own titles, buttons, or even controls. The navigation controller can also add a toolbar at the bottom of the display, which you can populate with buttonsand indicators. Both of these elements are owned and managed by the navigation controller.

n     Use a navigation controller when there are several layers of modal views, to keep the user informed about where they are, where they came from, and provide a consistent method of returning.

The UITabBarController manages a set of view controllers the user can maneuver through arbitrarily. Each view controller is represented by a button in a tab bar at the bottom of the screen. Tap a button and that view controllerappears. The iOS Clock app is a perfect example.

n     Use a tab bar to allow quick and direct access to functionally different areas of your app.

The UIPageViewController is equally easy to understand. It presents a sequence of view controllers, one at a time. The user navigates to the next, or previous, view controller in the sequence by tapping or swiping on the screen, asif leafing through the pages of a book. Apples Weather app is the iconic example of a page view controller in action.

n     Use a page view controller, as an alternative to UIScrollView, when you have more information than can be presented on a single screen or an unbounded set of functionally similar screens that differ only incontent.

The UISplitViewController is a navigation controller that eliminates the need for navigation. This special container view controller simultaneously presents two view controllers, side-by-side, on
an iPad. With the iPads additional screen space, an interface that had a list in one screen and the details of an item on a second can be presented as a unified interface, creating a much simpler and fluid experience. A splitview controller is part of your MyStuff app.

n     Use a split view controller on the iPad to present more content on a single screen, reducing the need for navigation.

Finally, its possible to create your own style of navigation. You can subclass UIViewController  and create a container view controller with whatever new kind of navigation you invent. I would, however, caution you about doing this.The existing navigation styles are successful largely because they are familiar to users. If you start designing spiral sidewalks, or streets that go backwards on Tuesdays, you might be creating a navigation nightmare, rather than navigation nirvana.

Wonderland Navigation

Considering all of the available options, the design for the Wonderland app is shown in Figure 12-1. The main screen—called the initial view controller—will be a tab view with three tabs. The first tab contains a content view withthe books title and an info button that (modally) presents some details about the author.


Figure 12-1. Wonderland app design

The middle tab lists characters in the book in a table viewTapping a row transitions to a detail view with more information. This interface is under the control of a navigation controller, so a navigation bar provides a way back tothe list.

The book appears in the last tab, a page view controller, where users can swipe and tap their way through the text. 

Creating Wonderland

Launch Xcode and create a new project. (I’m sure you saw that one coming.) This time, create the project based on the Tabbed  Application template. Name the app Wonderland, use a class prefix of WL, and make it Universal,as shown in Figure 12-2.


Figure 12-2. Project options for Wonderland

The initial view controller presented by your app will be a tab bar controller; the Tabbed Application template creates a project whose initial view controller is a tab bar controller. By cleverly choosing the Tabbed Application template, your first step is already done. You’ve created UITabBarController object and installed it as the apps initial view controller.

Tip    The initial view controller  is the view controller  presented when your app starts. You can create it programmatically in the startup code of your application delegate object or you can let iOS present it for you.For the latter to happen, you need to set its Is Initial View Controller property
(see Figure 12-3).
You can set this in Interface Builder by checking the Is Initial View Controller option using the attributes inspector, or bydragging around the initial view controller arrow (shown on the left side of the tab bar controller object in Figure 12-3) and attaching it to the view controller of your choice.


Figure 12-3. Starting tab bar configuration


Remember that a tab bar controller is a container view controller. It doesnt display (much) content of its own. Select the Main_iPhone.storyboard Interface Builder file, as shown in Figure 12-3. The big blank area in the middle ofthe tab view controller is going to be filled in with the contents of some other view controller. It shows that your tab bar controller comes pre-configured with two content view controllers, WLFirstViewController andWLSecondViewController.

To use a tab bar, you must provide a pair of objects for each tab: a view controller to display and a tab bar item (UITabBarItem) that configures that tabs button at the bottom of the screen. Each tab bar item defines a title andan icon. Icons smell suspiciously like resource files, so start there.


Adding Wonderlands Resources

I’m going to have you cheat (a little bit) and add all of the resources for this project at once. This will save you (me) from repeating these steps over again for each interface you’re going to develop in this chapter. Just add themall now; I’ll explain them later as you need them.

In earlier projects, I had you add individual resource files to the main top-level group (the folder icon) in your project navigator or to the Images.xcasset assest catalog. There are a sufficient number of resource files in this projectthat I’m going to have you create sub-groups so they dont become unwieldy. There are three ways you can organize source files in your project:

n     Create a sub-group and then create or add new files to that group

n     Import folders of source files and let the Xcode create groups for each folder

n     Wait until you have too many files cluttering up your navigator and then decide to organize them

To use the first or last method, create a new sub-group using the File  New Group command (also available by right/control+clicking  in the project navigator). Name the new group and then import resource files, create new source files, or drag existing files into it. Developers tend to either organize their groups by file type (all of the data files in one group, class source files in another) or by functional unit (all of the source and resources files for atable in a single group). Its a matter of style and personal preference.

The middle method is handy when you’re importing a large number of resource files at once. Find the Learn  iOS Development  Projects  Ch 12  Wonderland  (Resources) folder. These resourcfiles have been organized intosubfolders: Data  Resources, Character  Images, Info Images, and
Tab Images. Instead of dragging the individual files into the project navigator, you’ll drag the folders into your project, importing all of the resource files at once. Begin with the data (non-image) files
in the Data  Resources folder. Drag that folder and drop it into the Wonderland group, as shown in Figure 12-4.


Figure 12-4. Adding a folder of resource files

When the import dialog appears, make sure the Create groups   for any  added  folders option is selected. This will turn each folders worth of resource files into group, as shown on the right in 
Figure 12-4.

To do something similar for your images, choose the Images.xcassets asset catalog item and drag
all three folders of images (Character  Images, Info Images, and Tab Images) into the catalogs group column,as shown in Figure 12-5. This will automatically create three groups of images, as shown on the right of Figure 12-5.


Figure 12-5. Importing groups of image files


In the interests of neatness, lets discard some detritus you dont need. Select the first and second image sets in the asset catalog. While holding down the command key, press the delete key (or choose Edit  Delete) toremove these items from your project.

Configuring a Tab Bar Item

Now that you have all of your resources, configure the tab bar for the first tab. Each tab button in
the tab bar is configured via a UITabBarItem object associated with its view controller. You’ll find this object in the scene that defines that view controller. Select the Main_iPad.storyboar(or _iPhone) file. 

Find and expand the first view controller group, as shown in Figure 12-6.
Select the Tab Bar  Item  - First object and use the attributes inspector to change its title to Welcome” and set its image to tab-info.


Figure 12-6. Configuring a tab bar item

You’ll repeat these steps for each content view you add to the tab bar. Now move on to the content for this first tab.

The First Content View Controller

The first tab presents a simple content view controller, based on UIViewController. The Xcode template has already created a custom view controller (WLFirstViewController) and attached it as the contents of the first tab. This is almost exactly what you want, so gut it and make it your own.

Select the Main_iPad.storyboard (or _iPhone) file. Double-click on the first view controller (upper- right) in the canvas to make it the focus. The view already contains some label and text view objects. Select these and delete them.

Using the object library, add two labels and one image view object. Using the attributes and size inspectors, set their properties as follows:

1.       First label

a.       Text: Alice’s  Adventures in  Wonderland

b.       Font: System  30.0  (iPad), System  16.0  (iPhone)

2.       Second Label

a.       Text: by  Lewis  Carroll

b.       Font: System  20.0  (iPad), System  13.0  (iPhone)

3.       Image View

a.       Image: info-alice

b.       Mode: Aspect  Fit

c.       Size: 480x480 (iPad), 320x320 (iPhone)

Arrange the views so they look something like those in Figure 12-7. 
You’re going to add an “info” button and have that present a modal view controller.
Start by adding the button. Drag a Button object into your interface. Use theattributes inspector to change the type to Info Dark, and position it just to the right of the “by Lewis Carroll” label, also shown in Figure 12-7.


Figure 12-7. Creating the first view controller interface

No comments:

Post a Comment