An Overview of iPad iOS 6 Table Views and Xcode Storyboards
Previous | Table of Contents | Next |
Using Xcode Storyboards to create an iOS 6 iPad Tab Bar Application | Using Xcode Storyboards to Build Dynamic iOS 6 iPad TableViews with Prototype Table View Cells |
Learn SwiftUI and take your iOS Development to the Next Level |
The UITableView component was developed originally for the iPhone and provides the cornerstone of the navigation system for many iPhone based applications. The original purpose of the table view was to provide a way to present information in a list format on the smaller iPhone screen whereby selecting an item from a table view causes a second view to appear containing more detailed information corresponding to the selected item. For example, both the iPhone Mail and Settings applications make extensive use of Table Views to present information to users in a list format and to enable users to drill down to more detailed information by selecting a particular list item.
In terms of the iPad, however, navigation is rarely handled in the same way as on the iPhone. The simple fact is that a table view that occupies an entire iPad display results in large amounts of wasted screen space.
Master-Detail based navigation of the type provided by the table view on the iPad is typically implemented using the Split View and Pop Over objects. The split view divides the screen into two panels consisting of master and detail panels. The master panel presents a range of items for the user to select. When a selection is made, the detail panel updates to present detailed information relating to that selection.
The reason for covering table views in an iPad development book is partly for the sake of completeness (you may, after all, have a valid reason for using a table view in a specific way), but primarily because the list of items in a split view master panel is typically presented using a table view. It is imperative, therefore, that you have an understanding of table views in order to be able to effectively use split views. Historically, table views have been one of the more complex areas of iOS user interface implementation. In recognition of this fact, Apple introduced ways to implement table views through the use of the Xcode Storyboard feature.
The goal of this chapter is to provide an overview of the concept of the UITableView class together with an introduction to the ways in which storyboards can be used to ease the table view implementation process. Once these basics have been covered a series of chapters, starting with Using Xcode Storyboards to Build Dynamic iOS 6 iPad TableViews with Prototype Table View Cells, will work through the creation of example projects intended to demonstrate the use of storyboards in the context of table views.
An Overview of the Table View
Table Views present the user with data in a list format and are represented by the UITableView class of the UIKit framework. The data is presented in rows, whereby the content of each row is implemented in the form of a UITableViewCell object. By default, each table cell can display a text label (textLabel), a subtitle (detailedTextLabel) and an image (imageView). More complex cells can be created by either adding subviews to the cell, or subclassing UITableViewCell and adding your own custom functionality and appearance.
Static vs. Dynamic Table Views
When implementing table views using an Xcode storyboard it is important to understand the distinction between static and dynamic tables. Static tables are useful in situations when a fixed number of rows need to be displayed in a table. The settings page for an application, for example, would typically have a predetermined number of configuration options and would be an ideal candidate for a static table.
Dynamic tables (also known as prototype-based tables), on the other hand, are intended for use when a variable number of rows need to be displayed from a data source. Within the storyboard editor, Xcode allows you to visually design a prototype table cell which will then be replicated in the dynamic table view at runtime in order to display data to the user.
The Table View Delegate and dataSource
Each table view in an application needs to have a delegate and a dataSource associated with it (with the exception of static tables which do not have data source). The dataSource implements the UITableViewDataSource protocol, which basically consists of a number of methods that define title information, how many rows of data are to be displayed, how the data is divided into different sections and, most importantly, supplies the table view with the cell objects to be displayed. The delegate implements the UITableViewDelegate protocol and provides additional control over the appearance and functionality of the table view including detecting when a user touches a specific row, defining custom row heights and indentations and also implementation of row deletion and editing functions.
Table View Styles
Table views may be configured to use either plain or grouped style. In the grouped style, the rows are grouped together in sections represented by rounded rectangles. For example, Figure 25-1 shows a table view configured to use the grouped style:
Figure 25-1
In the case of the plain style, the items are listed without separation and using the full width of the display:
Figure 25-2
Table Views using plain style can also be indexed, whereby rows are organized into groups according to specified criteria, such as alphabetical or numerical sorting.
Table View Cell Styles
- UITableViewCellStyleDefault – only the labelText in black and left aligned.
- UITableViewCellStyleSubtitle – labelText in black and left aligned with the detailLabeltext positioned beneath it in a smaller font using a gray foreground.
- UITableViewCellStyleValue1 – labelText in black left aligned and the smaller detailLabelText in blue, on the same line and right aligned.
- UITableViewCellStyleValue2 – labelText in blue on left side of cell, right aligned and detailedLabelText on right of cell, left aligned and black.
Table View Cell Reuse
A table view is, at the basic level, comprised of a UITableView object and a UITableViewCell for each row to be displayed. When developing using iOS releases prior to iOS 6, it was the responsibility of the developer to write code to create instances of the cells as required by the table view object. In iOS 6 this has changed.
The code for a typical iOS 6 application using a table view will not directly create instances of a cell. The reasoning behind this becomes evident when performance and memory requirements are taken into consideration. Consider, for example, a table view that is required to display 1000 photo images. It can be assumed with a reasonable degree of certainty that only a small percentage of cells will be visible to the user at any one time. If the application was permitted to create each of the 1000 cells in advance the device would very quickly run into memory and performance limitations.
Instead, the application begins by registering with the table view object the class to be used for cell objects, along with the reuse identifier previously assigned to that class. If the cell class was written in code, the registration is performed using the registerClass: method of UITableView object. For example:
[self.tableView registerClass:[CarTableViewCell class] forCellWithReuseIdentifier:@"carTableCell"];
In the event that the cell is contained within an Interface Builder NIB file, the registerNib: method is used instead.
Perhaps the most important point to remember from this chapter is that if the cell is created using prototypes within a storyboard it is not necessary to register the class and, in fact, doing so will prevent the cell or view from appearing when the application runs.
As the table view initializes, it calls the cellForRowAtIndexPath: method of the datasource class passing through the index path for which a cell object is required. This method will then call the dequeueReusableCellWithReuseIdentifier: method of the table view object, passing through both the index path and the reuse ID assigned to the cell class when it was registered, to find out if there is a reusable cell object in the queue that can be used for this new cell. Since this is the initialization phase and no cells have been deemed eligible for reuse, the method will create a new cell and return it. Once all the visible cells have been created, the table view will stop asking for more cells. The code for the cellForCellAtIndexPath: will typically read as follows (the code to customize the cell before returning it will be implementation specific):
</pre> - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"carTableCell"; CarTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell here ...
return cell;
} </pre>
Developers familiar with Table Views in iOS 5 or older will note the absence in the above delegate method of the following line of code which used to be required to create table cells:
// This step no longer required in iOS 6 if (cell == nil) { cell = [[CarTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; }
As the user scrolls through the table view, some cells will move out of the visible frame. When this happens, the table view places them on the reuse queue. As cells are moving out of view, new ones are likely to be coming into view. For each cell moving into the view area, the table view will call cellForRowAtIndexPath:. This time, however, when a call to dequeueReusableCellWithReuseIdentifier: is made, it is most likely that an existing cell object will be returned from the reuse queue, thereby avoiding the necessity to create a new object.
Summary
Whilst table views provide a popular mechanism for displaying data and implementing view navigation within applications, implementation has historically been a complex process. That changed with the introduction of storyboard support in Xcode. Xcode now provides a mechanism for visually implementing a considerable amount of Table View functionality with minimal coding. Such table views can be implemented as either static or dynamic depending on the requirements of the table and the nature of the data being displayed.
Learn SwiftUI and take your iOS Development to the Next Level |
Previous | Table of Contents | Next |
Using Xcode Storyboards to create an iOS 6 iPad Tab Bar Application | Using Xcode Storyboards to Build Dynamic iOS 6 iPad TableViews with Prototype Table View Cells |