14
UINavigationController

In Chapter 5, you learned about UITabBarController and how it allows a user to access different screens. A tab bar controller is great for screens that are independent of each other, but what if you have screens that provide related information?

For example, the Settings application has multiple related screens of information: a list of settings (like Sounds), a detailed page for each setting, and a selection page for each detail (Figure 14.1). This type of interface is called a drill-down interface.

Figure 14.1  Drill-down interface in Settings

Figure shows a drill-down interface of sound settings in iOS.

In this chapter, you will use a UINavigationController to add a drill-down interface to Homepwner that lets the user see and edit the details of an Item. These details will be presented by the DetailViewController that you created in Chapter 13 (Figure 14.2).

Figure 14.2  Homepwner with UINavigationController

Homepwner with UINavigationController

UINavigationController

A UINavigationController maintains an array of view controllers presenting related information in a stack. When a UIViewController is on top of the stack, its view is visible.

When you initialize an instance of UINavigationController, you give it a UIViewController. This UIViewController is added to the navigation controller’s viewControllers array and becomes the navigation controller’s root view controller. The root view controller is always on the bottom of the stack. (Note that while this view controller is referred to as the navigation controller’s root view controller, UINavigationController does not have a rootViewController property.)

More view controllers can be pushed on top of the UINavigationController’s stack while the application is running. These view controllers are added to the end of the viewControllers array that corresponds to the top of the stack. UINavigationController’s topViewController property keeps a reference to the view controller at the top of the stack.

When a view controller is pushed onto the stack, its view slides onscreen from the right. When the stack is popped (i.e., the last item is removed), the top view controller is removed from the stack and its view slides off to the right, exposing the view of the next view controller on the stack, which becomes the top view controller. Figure 14.3 shows a navigation controller with two view controllers. The view of the topViewController is what the user sees.

Figure 14.3  UINavigationController’s stack

Illustration shows the UINavigationController stack.

UINavigationController is a subclass of UIViewController, so it has a view of its own. Its view always has two subviews: a UINavigationBar and the view of topViewController (Figure 14.4).

Figure 14.4  A UINavigationController’s view

Illustration shows the view of the UINavigationController.

In this chapter, you will add a UINavigationController to the Homepwner application and make the ItemsViewController the UINavigationController’s root view controller. The DetailViewController will be pushed onto the UINavigationController’s stack when an Item is selected. This view controller will allow the user to view and edit the properties of an Item selected from the table view of ItemsViewController. The object diagram for the updated Homepwner application is shown in Figure 14.5.

Figure 14.5  Homepwner object diagram

Illustration shows the Homepwner object diagram.

This application is getting fairly large, as you can see. Fortunately, view controllers and UINavigationController know how to deal with this type of complicated object diagram. When writing iOS applications, it is important to treat each UIViewController as its own little world. The stuff that has already been implemented in Cocoa Touch will do the heavy lifting.

Begin by giving Homepwner a navigation controller. Reopen the Homepwner project. The only requirements for using a UINavigationController are that you give it a root view controller and add its view to the window.

Open Main.storyboard and select the Items View Controller. Then, from the Editor menu, choose Embed InNavigation Controller. This will set the ItemsViewController to be the root view controller of a UINavigationController. It will also update the storyboard to set the Navigation Controller as the initial view controller.

Your Detail View Controller interface may have misplaced views now that it is contained within a navigation controller. If it does, select the stack view and click the Update Frames button in the Auto Layout constraint menu.

Build and run the application and … the application crashes. What is happening? You previously created a contract with the AppDelegate that an instance of ItemsViewController would be the rootViewController of the window:

let itemsController = window!.rootViewController as! ItemsViewController

You have now broken this contract by embedding the ItemsViewController in a UINavigationController. You need to update the contract.

Open AppDelegate.swift and update application(_:didFinishLaunchingWithOptions:) to reflect the new view controller hierarchy.

func application(_ application: UIApplication, didFinishLaunchingWithOptions
        launchOptions: [UIApplicationLaunchOptionsKey : Any]?) -> Bool {
    // Override point for customization after application launch.

    // Create an ItemStore
    let itemStore = ItemStore()

    // Access the ItemsViewController and set its item store
    let itemsController = window!.rootViewController as! ItemsViewController
    let navController = window!.rootViewController as! UINavigationController
    let itemsController = navController.topViewController as! ItemsViewController
    itemsController.itemStore = itemStore

    return true
}

Build and run the application again. Homepwner works again and has a very nice, if totally empty, UINavigationBar at the top of the screen (Figure 14.6).

Figure 14.6  Homepwner with an empty navigation bar

Screenshot of a view controller with an empty navigation bar is shown. Two labels: Fluffy Spork and Rusty Bear are listed with a price label mentioned across each. Two buttons: Edit and Add are present on the labels.

Notice how the screen adjusted to fit ItemsViewController’s view as well as the new navigation bar. UINavigationController did this for you: While the view of the ItemsViewController actually underlaps the navigation bar, UINavigationController added padding to the top so that everything fits nicely. This is because the top layout guide for the view controller is adjusted, along with any views constrained to the top layout guide – like the stack view.

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

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