Implementing iPad TableView Navigation using Xcode Storyboards

From Techotopia
Revision as of 19:48, 10 May 2016 by Neil (Talk | contribs) (Text replacement - "<!-- Ezoic - BottomOfPage - bottom_of_page --> <div id="ezoic-pub-ad-placeholder-114"></div> <!-- End Ezoic - BottomOfPage - bottom_of_page -->" to "<htmlet>ezoicbottom</htmlet>")

Jump to: navigation, search
PreviousTable of ContentsNext
Using Xcode Storyboards to Build Dynamic iPad TableViews with Prototype Table View CellsUsing an Xcode Storyboard to Create a Static iPad Table View


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 Storyboards to Build Dynamic iPad TableViews with Prototype Table View Cells) and, in so doing, demonstrate the steps involved in implementing table view navigation within a storyboard. In other words, we will be modifying the car example from the previous chapter such that selecting a row from the table view displays a second scene containing additional information about the selected car. 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.

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 ViewController 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 Objective-C class option. On the options screen, make sure that the Subclass of menu is set to UIViewController, name the new class CarDetailViewController and make sure that the Targeted for iPad option is on and With XIB file for user interface option is off. Next, select the MainStoryboard.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 21 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 CarDetailViewController.


Adding a second scene to an iPad iOS 5 table view based storyboard

Figure 21-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.


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 segue 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 Car 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 21-2:

Adding a navigation controller to a storyboard

Figure 21-2


Establishing the Storyboard Segue

When the user selects a row within the table view a segue needs to be triggered to display the car detail view controller. In order to establish this segue, Ctrl-click on the prototype cell located in the Car Table View Controller scene and drag the resulting line to the Car Detail View Controller scene. Upon releasing the line, select the Push option from the resulting menu (note that this step can only be performed if the storyboard is currently zoomed in). The storyboard will update to display a segue connection between the table view 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 Car Table View Controller and Car Detail View Controller, display the Attributes Inspector (View -> Utilities -> Show Attributes Inspector) and change the Identifier value to ShowCarDetails.

In addition, a toolbar should have appeared in both scenes. Double click on these toolbars and change the title to “Cars” and “Car Details” respectively:


Establishing an Xcode Storyboard segue

Figure 21-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 table view. Clearly, we now need to do some work on the CarDetailViewController class so that details about the selected car are displayed in the view.

Modifying the CarDetailViewController Class

For the purposes of this example application, the car detail view is going to display the make and model of the selected car together with a photograph. In order to achieve this, the class is going to need outlets to two labels and a UIImageView object which will later be added to the view.

In addition to the outlets, the class is also going to need an internal data model that contains information about the car. It will be the job of the table view controller to update this model prior to the segue occurring so that it reflects data on the selected car. For the sake of simplicity, the data model will take the form of an NSArray object. Select the CarDetailViewController.h file and modify it as follows:

#import <UIKit/UIKit.h>

@interface CarDetailViewController : UIViewController

@property (strong, nonatomic) NSArray *carDetailModel;
@property (strong, nonatomic) IBOutlet UILabel *makeLabel;
@property (strong, nonatomic) IBOutlet UILabel *modelLabel;
@property (strong, nonatomic) IBOutlet UIImageView *imageView;
@end

Next, modify the CarDetailViewController.m file to add the corresponding @synthesize directive. When the view appears it will also need to be updated with the information from the data model using the outlets declared above. This can be achieved by adding code to the viewDidLoad: method as follows:

#import "CarDetailViewController.h"

@implementation CarDetailViewController
@synthesize makeLabel;
@synthesize modelLabel;
@synthesize imageView;
@synthesize carDetailModel;

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.makeLabel.text = [self.carDetailModel objectAtIndex:0];
    self.modelLabel.text = [self.carDetailModel objectAtIndex:1];
    self.imageView.image = [UIImage imageNamed: 
         [self.carDetailModel objectAtIndex:2]];
}

Having declared the outlets, the next step is to design the user interface for the detail view and connect the user interface elements to those outlets. Select the storyboard file in the navigation controller, ensure that the view is zoomed in and drag and drop items from the object library so that the user interface appears as illustrated in Figure 21-4:


The UI of the example iPad iOS 5 storyboard detail scene

Figure 21-4


Move the mouse pointer to the status bar at the top of the scene (the grey bar contain the battery level indicator). Ctrl-click on the bar and drag the line to the label located to the right of the “Make” label as shown in Figure 21 5. Release the line and select makeLabel from the menu of outlets. Repeat these steps to establish connections to the modelLabel and imageView outlets respectively.


Establishing table view outlet connections in a storyboard

Figure 21-5


Using prepareForSegue: 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 CarDetailViewController class is updated with details of the selected car when a table view row is touched by the user. As previously outlined in Using Xcode Storyboarding with iOS 5, the prepareForSegue: 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 prepareForSegue: method needs to be added to the CarTableViewController.m file as outlined in the following code fragment. Note that since the code will need to access an instance of CarDetailViewController it is also necessary to import the CarDetailViewController.h file:

#import "CarTableViewController.h"
#import "CarTableViewCell.h"
#import "CarDetailViewController.h"
.
.
.

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([[segue identifier] isEqualToString:@"ShowCarDetails"])
    {
        CarDetailViewController *detailViewController = 
           [segue destinationViewController];

        NSIndexPath *myIndexPath = [self.tableView 
           indexPathForSelectedRow];

        detailViewController.carDetailModel = [[NSArray alloc]
             initWithObjects: [self.carMakes 
                objectAtIndex:[myIndexPath row]],
             [self.carModels objectAtIndex:[myIndexPath row]],
             [self.carImages objectAtIndex:[myIndexPath row]],
             nil];
    }
}


The first task performed by this method is to check that the triggering segue is the ShowCarDetails 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 CarDetailViewController 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 data in the CarDetailViewController instance’s carDataModel array property.

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 in the iOS Simulator. Select a car from the table and watch as the second view controller appears primed with data about the car:


An iPad iOS 5 TableView Storyboard app detail screen

Figure 21-6

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 prepareForSeque: method as a mechanism for passing data during a segue 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 Storyboards to Build Dynamic iPad TableViews with Prototype Table View CellsUsing an Xcode Storyboard to Create a Static iPad Table View