Implementing iOS 10 TableView Navigation using Storyboards in Xcode 8

From Techotopia
Revision as of 04:24, 10 November 2016 by Neil (Talk | contribs) (Modifying the AttractionDetailViewController Class)

Jump to: navigation, search

PreviousTable of ContentsNext
Using Xcode 8 Storyboards to Build Dynamic TableViewsWorking with the iOS 10 Stack View Class


Learn SwiftUI and take your iOS Development to the Next Level
SwiftUI Essentials – iOS 16 Edition book is now available in Print ($39.99) and eBook ($29.99) editions. Learn more...

Buy Print Preview Book


The objective of this chapter is to extend the application created in the previous chapter (entitled Using Xcode 8 Storyboards to Build Dynamic TableViews) and, in so doing, demonstrate the steps involved in implementing table view navigation within a storyboard. In other words, we will be modifying the attractions example from the previous chapter such that selecting a row from the table view displays a second scene in which a web page providing information about the chosen location will be displayed to the user. As part of this exercise we will also explore the transfer of data between different scenes in a storyboard.


Contents


Understanding the Navigation Controller

Navigation based applications present a hierarchical approach to displaying information to the user. Such applications typically take the form of a navigation bar (UINavigationBar) and a series of Table based views (UITableView). Selecting an item from the table list causes the view associated with that selection to be displayed. The navigation bar will display a title corresponding to the currently displayed view together with a button that returns the user to the previous view when selected. For an example of this concept in action, spend some time using the iPhone Mail or Music applications.

When developing a navigation-based application, the central component of the architecture is the navigation controller. In addition, each scene has a view and a corresponding view controller. The navigation controller maintains a stack of these view controllers. When a new view is displayed it is pushed onto the navigation controller’s stack and becomes the currently active controller. The navigation controller automatically displays the navigation bar and the “back” button. When the user selects the button in the navigation bar to move back to the previous level, that view controller is popped off the stack and the view controller beneath it moved to the top becoming the currently active controller.

The view controller for the first table view that appears when the application is started is called the root view controller. The root view controller cannot be popped off the navigation controller stack.

Adding the New Scene to the Storyboard

For the purposes of this example we will be adding a new View Controller to our storyboard to act as the second scene. With this in mind, begin by loading the TableViewStory project created in the previous chapter into Xcode. Once the project has loaded we will need to add a new UIViewController subclass to our project files so select the File -> New -> File… menu item and choose the Cocoa Touch Class option from the iOS Source category. On the options screen, make sure that the Subclass of menu is set to UIViewController, name the new class AttractionDetailViewController and make sure that the Also create XIB file option is switched off. Click Next before clicking on Create.

Next, select the Main.storyboard file from the project navigator so that the storyboard canvas is visible. From the Object Library, select a View Controller and drag and drop it to the right of the existing table view controller as outlined in Figure 30 1. With the new view controller added, select it and display the identity inspector (View -> Utilities -> Show Identity Inspector) and change the class setting from UIViewController to AttractionDetailViewController.


The storyboard with a second view controller added

Figure 30-1


The detail scene has now been added and assigned to the newly created subclass where code can be added to bring the scene to life.

Learn SwiftUI and take your iOS Development to the Next Level
SwiftUI Essentials – iOS 16 Edition book is now available in Print ($39.99) and eBook ($29.99) editions. Learn more...

Buy Print Preview Book


Adding a Navigation Controller

Once the application is completed, selecting a row from the Table View will trigger a segue to display the detail view controller. The detail view will contain a button which, when selected by the user, will navigate back to the table view. This functionality will be made possible by the addition of a Navigation Controller to the storyboard. This can be added by selecting the Attraction Table View Controller item in the storyboard so that it highlights in blue, and then selecting the Xcode Editor -> Embed In -> Navigation Controller menu option. Once performed, the storyboard will appear as outlined in Figure 30-2:


The storyboard with a navigation controller

Figure 30-2

Establishing the Storyboard Segue

When the user selects a row within the table view, a segue needs to be triggered to display the attraction detail view controller. In order to establish this segue, Ctrl-click on the prototype cell located in the Attraction Table View Controller scene and drag the resulting line to the Attraction Detail View Controller scene. Upon releasing the line, select the show option from the resulting menu. The storyboard will update to display a segue connection between the table view cell and the view controller. In code that will be implemented later in this chapter it will be necessary to reference this specific segue. In order to do so it must, therefore, be given an identifier. Click on the segue connection between Attraction Table View Controller and Attraction Detail View Controller, display the Attributes Inspector (View -> Utilities -> Show Attributes Inspector) and change the Identifier value to ShowAttractionDetails.

In addition, a toolbar should have appeared in both scenes. Double-click on the center of the Attraction Table View Controller toolbar and change the title to “Attractions”. Next, drag a Navigation Item view from the Object Library and drop it onto the toolbar of the Attraction Detail View Controller. Double-click on the Title and change it to “Attraction Details”:


The full storyboard with a segue added

Figure 30-3


Build and run the application and note that selecting a row in the table view now displays the second view controller which, in turn, has a button in the toolbar to return to the “Attractions” table view. Clearly, we now need to do some work on the AttractionDetailViewController class so that information about the selected tourist location is displayed in the view.

Modifying the AttractionDetailViewController Class

For the purposes of this example application, the attraction detail view is going to display a web view loaded with a web page relating to the selected tourist attraction. In order to achieve this, the class is going to need a UIWebView object which will later be added to the view.

In addition to the web view, the class is also going to need an internal data model that contains the URL of the web page to be displayed. It will be the job of the table view controller to update this variable prior to the segue occurring so that it reflects the selected attraction. For the sake of simplicity, the data model will take the form of a String object. Select the AttractionDetailViewController.swift file and modify it as follows to declare this variable:

import UIKit

class AttractionDetailViewController: UIViewController {

    var webSite: String?
.
.
.

Learn SwiftUI and take your iOS Development to the Next Level
SwiftUI Essentials – iOS 16 Edition book is now available in Print ($39.99) and eBook ($29.99) editions. Learn more...

Buy Print Preview Book

The next step is to add the Web View to the view controller. Select the storyboard file in the Project Navigator, and drag and drop a Web View from the Object Library onto the Attraction Detail scene. Resize the view so that it fills the entire scene area as illustrated in Figure 30-4:

A WebView added to the detail view controller

Figure 30-4


With the Web View selected in the storyboard canvas, display the Auto Layout Add New Constraints menu and add Spacing to nearest neighbor constraints on all four sides of the view with the Constrain to margins option disabled.

Display the Assistant Editor panel and verify that the editor is displaying the contents of the AttractionDetailViewController.swift file. Ctrl-click on the Web View and drag to a position just below the class declaration line in the Assistant Editor. Release the line and in the resulting connection dialog establish an outlet connection named webView.

When the detail view appears, the Web View will need to load the web page referenced by the webSite string variable. This can be achieved by adding code to the viewDidLoad method of the AttractionDetailViewController.swift file as follows:

override func viewDidLoad() {
    super.viewDidLoad()

   if let address = webSite {
        let webURL = URL(string: address)
        let urlRequest = URLRequest(url: webURL!)
        webView.loadRequest(urlRequest)
    }
}

Using prepare(for segue:) to Pass Data between Storyboard Scenes

The last step in the implementation of this project is to add code so that the data model contained within the AttractionDetailViewController class is updated with the URL of the selected attraction when a table view row is touched by the user. As previously outlined in Using Storyboards in Xcode 8, the prepare(for segue:) method on an originating scene is called prior to a segue being performed. This is the ideal place to add code to pass data between source and destination scenes. The prepare(for segue:) method needs to be added to the AttractionTableViewController.swift file as outlined in the following code fragment:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
   if segue.identifier == "ShowAttractionDetails" {

       let detailViewController = segue.destination
            as! AttractionDetailViewController

       let myIndexPath = self.tableView.indexPathForSelectedRow!
       let row = myIndexPath.row
       detailViewController.webSite = webAddresses[row]
    }
}

Learn SwiftUI and take your iOS Development to the Next Level
SwiftUI Essentials – iOS 16 Edition book is now available in Print ($39.99) and eBook ($29.99) editions. Learn more...

Buy Print Preview Book

The first task performed by this method is to check that the triggering segue is the ShowAttractionDetails segue we added to the storyboard. Having verified that to be the case the code then obtains a reference to the view controller of the destination scene (in this case an instance of our AttractionDetailViewController class). The table view object is then interrogated to find out the index of the selected row which, in turn, is used to prime the URL string variable in the AttractionDetailViewController instance.

Testing the Application

The final step is to compile and run the application. Click on the run button located in the Xcode toolbar and wait for the application to launch. Select an entry from the table and watch as the second view controller appears and loads the appropriate web page:


The example iOS table view app running

Figure 30-5

Summary

A key component of implementing table view navigation using storyboards involves the use of segues and the transfer of data between scenes. In this chapter we have used a segue to display a second scene based on table view row selections. The use of the prepare(for segue:) method as a mechanism for passing data during a segue has also been explored and demonstrated.


Learn SwiftUI and take your iOS Development to the Next Level
SwiftUI Essentials – iOS 16 Edition book is now available in Print ($39.99) and eBook ($29.99) editions. Learn more...

Buy Print Preview Book



PreviousTable of ContentsNext
Using Xcode 8 Storyboards to Build Dynamic TableViewsWorking with the iOS 10 Stack View Class