34,333
edits
Changes
New page: <table border="0" cellspacing="0" width="100%"> <tr> <td width="20%">Previous<td align="cent...
<table border="0" cellspacing="0" width="100%">
<tr>
<td width="20%">[[Using Xcode Storyboards to Build Dynamic TableViews with Prototype Table View Cells (iOS 6)|Previous]]<td align="center">[[iPhone iOS 6 Development Essentials|Table of Contents]]<td Width="20%" align="right">[[26. Using an Xcode Storyboard to Create a Static Table View (iOS 6)|Next]]</td>
<tr>
<td width="20%">Using Xcode Storyboards to Build Dynamic TableViews with Prototype Table View Cells<td align="center"><td width="20%" align="right">Using an Xcode Storyboard to Create a Static Table View</td>
</table>
<hr>
<google>BUY_IOS6</google>
The objective of this chapter is to extend the application created in the previous chapter (entitled Using Xcode Storyboards to Build Dynamic 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.
== 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 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 and With XIB file for user interface options are 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 25-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.
[Image:iphone_ios_5_table_view_storyboard_viewcontroller_added.jpg|A Storyboard containing a table view and view controller]]
Figure 25-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 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 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 25 2:
[[Image:iphone_ios_5_storyboard_navigation_controller.jpg|An Xcode iOS 5 storyboard with a table view and embedded view controller]]
Figure 25-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. 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 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:
[[Image:iphone_ios_5_table_cell_segue.jpg|A table view storyboard with an embedded navigation controller and a segue]]
Figure 25-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 to declare this array:
<pre>
#import <UIKit/UIKit.h>
@interface CarDetailViewController : UIViewController
@property (strong, nonatomic) NSArray *carDetailModel;
@end
</pre>
The next step is to design the user interface for the detail view and connect the user interface elements to outlet properties. 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 25-4:
[[Image:iphone_ios_5_table_segue_view_ui.jpg|Designing the user interface of a storyboard view]]
Figure 25-4
Select the label to the right of the “Make” label in the view canvas, display the Assistant Editor panel and verify that the editor is displaying the contents of the CarDetailViewController.h file. Ctrl-click on the label again and drag to a position just below the @interface line in the Assistant Editor. Release the line and in the resulting connection dialog establish an outlet connection named makeLabel. Repeat these steps to establish outlet connections for the second label (the one located to the right of the “Model” label) and the image view to properties named modelLabel and imageView respectively.
On completion of the outlet connections, the CarDetailViewController.h should read as follows:
<pre>
#import <UIKit/UIKit.h>
@interface CarDetailViewController : UIViewController
@property (strong, nonatomic) IBOutlet UILabel *makeLabel;
@property (strong, nonatomic) IBOutlet UILabel *modelLabel;
@property (strong, nonatomic) IBOutlet UIImageView *imageView;
@property (strong, nonatomic) NSArray *carDetailModel;
@end
</pre>
When the detail view appears, the user interface objects will need to be updated with items from the data model array. This can be achieved by adding code to the viewDidLoad: method of the CarDetailViewController.m file as follows:
<pre>
- (void)viewDidLoad
{
[super viewDidLoad];
_makeLabel.text = _carDetailModel[0];
_modelLabel.text = _carDetailModel[1];
_imageView.image = [UIImage imageNamed:_carDetailModel[2]];
}
</pre>
== 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, 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:
<pre>
#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];
int row = [myIndexPath row];
detailViewController.carDetailModel = @[_carMakes[row],
_carModels[row], _carImages[row]];
}
}
</pre>
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:
[[Image:iphone_ios_5_storyboard_scene_outlet_connect.jpg|Connecting table view storyboard objects to outlets]]
Figure 25-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 prepareForSeque: method as a mechanism for passing data during a segue also been explored and demonstrated.
<google>BUY_IOS6</google>
<hr>
<table border="0" cellspacing="0" width="100%">
<tr>
<td width="20%">[[Using Xcode Storyboards to Build Dynamic TableViews with Prototype Table View Cells (iOS 6)|Previous]]<td align="center">[[iPhone iOS 6 Development Essentials|Table of Contents]]<td Width="20%" align="right">[[26. Using an Xcode Storyboard to Create a Static Table View (iOS 6)|Next]]</td>
<tr>
<td width="20%">Using Xcode Storyboards to Build Dynamic TableViews with Prototype Table View Cells<td align="center"><td width="20%" align="right">Using an Xcode Storyboard to Create a Static Table View</td>
</table>
<tr>
<td width="20%">[[Using Xcode Storyboards to Build Dynamic TableViews with Prototype Table View Cells (iOS 6)|Previous]]<td align="center">[[iPhone iOS 6 Development Essentials|Table of Contents]]<td Width="20%" align="right">[[26. Using an Xcode Storyboard to Create a Static Table View (iOS 6)|Next]]</td>
<tr>
<td width="20%">Using Xcode Storyboards to Build Dynamic TableViews with Prototype Table View Cells<td align="center"><td width="20%" align="right">Using an Xcode Storyboard to Create a Static Table View</td>
</table>
<hr>
<google>BUY_IOS6</google>
The objective of this chapter is to extend the application created in the previous chapter (entitled Using Xcode Storyboards to Build Dynamic 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.
== 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 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 and With XIB file for user interface options are 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 25-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.
[Image:iphone_ios_5_table_view_storyboard_viewcontroller_added.jpg|A Storyboard containing a table view and view controller]]
Figure 25-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 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 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 25 2:
[[Image:iphone_ios_5_storyboard_navigation_controller.jpg|An Xcode iOS 5 storyboard with a table view and embedded view controller]]
Figure 25-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. 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 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:
[[Image:iphone_ios_5_table_cell_segue.jpg|A table view storyboard with an embedded navigation controller and a segue]]
Figure 25-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 to declare this array:
<pre>
#import <UIKit/UIKit.h>
@interface CarDetailViewController : UIViewController
@property (strong, nonatomic) NSArray *carDetailModel;
@end
</pre>
The next step is to design the user interface for the detail view and connect the user interface elements to outlet properties. 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 25-4:
[[Image:iphone_ios_5_table_segue_view_ui.jpg|Designing the user interface of a storyboard view]]
Figure 25-4
Select the label to the right of the “Make” label in the view canvas, display the Assistant Editor panel and verify that the editor is displaying the contents of the CarDetailViewController.h file. Ctrl-click on the label again and drag to a position just below the @interface line in the Assistant Editor. Release the line and in the resulting connection dialog establish an outlet connection named makeLabel. Repeat these steps to establish outlet connections for the second label (the one located to the right of the “Model” label) and the image view to properties named modelLabel and imageView respectively.
On completion of the outlet connections, the CarDetailViewController.h should read as follows:
<pre>
#import <UIKit/UIKit.h>
@interface CarDetailViewController : UIViewController
@property (strong, nonatomic) IBOutlet UILabel *makeLabel;
@property (strong, nonatomic) IBOutlet UILabel *modelLabel;
@property (strong, nonatomic) IBOutlet UIImageView *imageView;
@property (strong, nonatomic) NSArray *carDetailModel;
@end
</pre>
When the detail view appears, the user interface objects will need to be updated with items from the data model array. This can be achieved by adding code to the viewDidLoad: method of the CarDetailViewController.m file as follows:
<pre>
- (void)viewDidLoad
{
[super viewDidLoad];
_makeLabel.text = _carDetailModel[0];
_modelLabel.text = _carDetailModel[1];
_imageView.image = [UIImage imageNamed:_carDetailModel[2]];
}
</pre>
== 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, 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:
<pre>
#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];
int row = [myIndexPath row];
detailViewController.carDetailModel = @[_carMakes[row],
_carModels[row], _carImages[row]];
}
}
</pre>
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:
[[Image:iphone_ios_5_storyboard_scene_outlet_connect.jpg|Connecting table view storyboard objects to outlets]]
Figure 25-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 prepareForSeque: method as a mechanism for passing data during a segue also been explored and demonstrated.
<google>BUY_IOS6</google>
<hr>
<table border="0" cellspacing="0" width="100%">
<tr>
<td width="20%">[[Using Xcode Storyboards to Build Dynamic TableViews with Prototype Table View Cells (iOS 6)|Previous]]<td align="center">[[iPhone iOS 6 Development Essentials|Table of Contents]]<td Width="20%" align="right">[[26. Using an Xcode Storyboard to Create a Static Table View (iOS 6)|Next]]</td>
<tr>
<td width="20%">Using Xcode Storyboards to Build Dynamic TableViews with Prototype Table View Cells<td align="center"><td width="20%" align="right">Using an Xcode Storyboard to Create a Static Table View</td>
</table>