In this tutorial we’re going to discuss and implement the TableView UI element in our iOS application.
iOS TableView Overview
A TableView is used to display a list of data in our application. It’s used for displaying a vertically scrollable view which consists of a number of cells that are reusable. Headers, footers, rows and sections can be included in such a UI element. Let’s jump onto the implementation of the TableView, from where we’ll give more insight to it’s working, usages and customisations. Create a new project first, following the same steps as shown in the previous tutorial.
Implementation
We’ll use an NSMutableArray
to hold the data that’ll be displayed in our TableView. Our ViewController would adopt the UITableViewDataSource and UITableViewDelegate as the protocols. Protocols are analogous to Interfaces. Basically, in order to display data in TableView, we have to conform to the requirements defined in the protocols and implement all the mandatory methods.
The ViewController.h
header file is defined below.
ViewController.h
1 2 3 4 5 6 7 8 9 10 |
#import <UIKit/UIKit.h> @interface ViewController : UIViewController<UITableViewDataSource, UITableViewDelegate> { IBOutlet UITableView *myTable; NSMutableArray *myArray; } @end |
UITableViewDelegate and UITableViewDataSource
UITableView is the base class that’s used to implement a TableView.
UITableViewDataSource protocol acts as a link between the data and the table view. This protocol consists of the following two methods that need to be implemented.
-
1(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:
-
1(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:
The implementation of the above two methods deals with specifying the number of rows and type of data in each row.
UITableViewDelegate protocol deals with the appearance of the TableView such as height of TableRow configure section headings and footers, re-order table cells etc.
Few methods of this protocol include:
-
1(NSString *)tableView:(UITableView *)tableView titleForFooterInSection:
-
1(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:
-
1(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
Now we need to implement the data source and delegate methods in the ViewController.m
file.
We’ll initialise the NSMutableArray in the viewDidLoad
method.
Before we do that let’s design the view in our StoryBoard.xib
file.
Search for TableView in the object attributes and drag and drop it over the view. Resize it to cover the screen leaving the space out for the status bar. Your screen should look similar to the one given below.
Note: Adding the IBOutlet for the TableView in the ViewController.h
file can be done in another way from the storyboard itself. Press option+command+Enter on the keyboard to open the assistant editor. Press control and drag the tableview to the editor as shown below and release it. Enter the variable name and choose the Storage type as strong.
We need to set the delegate and datasource for the tableview onto the file owner icon at the top of the dock. Press control and drag the tableview to it. Release the click and chose datasource to make a connection. Do the same for the delegate.
To ensure that the connections are properly made look into the connections inspector tab in the right pane.
The ViewController.m
file contains the implementation part of the protocol methods that we had defined earlier. It’s given below
ViewController.m
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
#import "ViewController.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. myArray = [[NSMutableArray alloc]initWithObjects: @"New Delhi",@"Mumbai",@"Hyderabad", @"Bangalore",@"Sydney",@"Melbourne", @"Brisbane",@"Perth",@"New York", @"Los Angeles",@"Chicago",@"Boston", nil]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } #pragma mark - Table View Data source - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection: (NSInteger)section{ return [myArray count]/3; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath{ static NSString *cellId = @"SimpleTableId"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: cellId]; if (cell == nil) { cell = [[UITableViewCell alloc]initWithStyle: UITableViewCellStyleDefault reuseIdentifier:cellId]; } NSString *stringForCell; if (indexPath.section == 0) { stringForCell= [myArray objectAtIndex:indexPath.row]; } else if (indexPath.section == 1){ stringForCell= [myArray objectAtIndex:indexPath.row+ [myArray count]/3]; } else if (indexPath.section == 2){ stringForCell= [myArray objectAtIndex:indexPath.row+ 2*[myArray count]/3]; } [cell.textLabel setText:stringForCell]; return cell; } // Default is 1 if not implemented - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ return 3; } - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection: (NSInteger)section{ NSString *headerTitle; if (section==0) { headerTitle = @"India"; } else if(section==1){ headerTitle = @"Australia"; } else{ headerTitle = @"United States of America"; } return headerTitle; } - (NSString *)tableView:(UITableView *)tableView titleForFooterInSection: (NSInteger)section{ NSString *footerTitle; if (section==0) { footerTitle = @"End of prominent cities of India"; } else if (section==1){ footerTitle = @"End of prominent cities of Australia"; } else if (section==2){ footerTitle = @"End of prominent cities of USA"; } return footerTitle; } #pragma mark - TableView delegate -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath: (NSIndexPath *)indexPath{ [tableView deselectRowAtIndexPath:indexPath animated:YES]; UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; NSLog(@"Section:%d Row:%d selected and its data is %@", indexPath.section,indexPath.row,cell.textLabel.text); } @end |
- The NSMutableArray is populated in the
viewDidLoad
method - Two sections with there separate headers and footers are defined
- The NSMutableArray data elements are divided into the two sections equally. The first half of the array goes into the first section and the other half into the second section
- NSLog is used to print the selected row index and its data
The output of the application in action is given below.
Note: As you can see we have grouped each section. This can be done from the attributes inspector pane by choosing the style as grouped.
Clicking a row prints a log in the XCode console as shown below.
This brings an end to this tutorial. We’ve developed a simple table view iOS Application with two sections in which the data is loaded from an array. This tutorial was aimed at getting familiar with the table view and implementing it’s methods. In general data is not always loaded from a array. It’s loading in other ways like from a file. We’ll discuss and implement them in later tutorials. You can download the iOS SimpleTable Project from the link given below.