Login | Register   
LinkedIn
Google+
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


advertisement
 

More Table View Tricks for the iPhone

Go beyond the basics of the iPhone Table View with examples for grouping rows into sections, displaying an index on the side, and adding a Search Bar.


advertisement
y previous article on using the Table View in iPhone discussed the basics of this view and how you can use it to display rows of data and how users can use it to drill into more details. However, you can do many more things with the Table View than what that article could possibly cover. Hence, this follow-up article covers some more uses of the Table View. Specifically, you will learn:
  • How to group the rows in a Table View into sections
  • How to display an index on the right side of the Table View so that users can directly jump to a particular section of the Table View simply by tapping on the index
  • How to add a Search Bar to the Table View so that users can search for rows in the Table View

Author's Note: For this article, I will extend the project created in the previous article. I suggest you download the project for the previous article if you want to follow the examples illustrated here.

Grouping the Rows in a Table View into Sections

The previous article's example stored a list of all the US states using an NSMutableArray object and displayed all 50 states in the Table View as a single section. It would be very useful to group the 50 states into sections, perhaps alphabetically. The Table View allows you to group rows into sections, so that users have a visual way of viewing related rows.



To group the states into sections, you first declare another NSMutableArray object named stateIndex in the RootViewController.m file:

#import "RootViewController.h" @implementation RootViewController @synthesize detailsViewController; NSMutableArray *listOfStates; NSMutableArray *stateIndex;

The stateIndex will be used to store the starting character of each state (i.e., “A”, “B”, “C”, etc.).

In the viewDidLoad method, add the following block of code in bold:

- (void)viewDidLoad { //---initialize--- listOfStates = [[NSMutableArray alloc] init]; //---add items--- [listOfStates addObject:@"ALABAMA"]; [listOfStates addObject:@"ALASKA"]; //... //... [listOfStates addObject:@"WISCONSIN"]; [listOfStates addObject:@"WYOMING"]; //---create the index--- stateIndex = [[NSMutableArray alloc] init]; for (int i=0; i<[listOfStates count]-1; i++){ //---get the first char of each state--- char alphabet = [[listOfStates objectAtIndex:i] characterAtIndex:0]; NSString *uniChar = [NSString stringWithFormat:@"%C", alphabet]; //---add each letter to the index array--- if (![stateIndex containsObject:uniChar]) { [stateIndex addObject:uniChar]; } } self.navigationItem.title = @"States of America"; [super viewDidLoad]; }

Rather than manually creating the index by adding “A”, “B”, “C”, etc., to the stateIndex object, you shall iterate through the listOfStates object and then extract the first character of each state. Each character extracted is then added into the stateIndex object. This approach is useful, as you can freely add or remove states from the listOfStates object. At the same time, the approach insures that certain characters (such as “B”) will not be added if there are no state names beginning with that particular character.

To insure that the Table View displays the rows in sections, implement the numberOfSectionsInTableView: method and return the size of the stateIndex object:

//---set the number of sections in the table--- - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return [stateIndex count]; }

For each section, you will display a header. In this case, you shall display the beginning character of each state. To display the header for each section, implement the tableView:titleForHeaderInSection: method:

//---set the title for each section--- - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { return [stateIndex objectAtIndex:section]; }

To set the number of rows in each section, you need to implement the tableView:numberOfRowsInSection: method:

//---set the number of rows in each section--- - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { //---get the letter in each section; e.g., A, B, C, etc.--- NSString *alphabet = [stateIndex objectAtIndex:section]; //---get all states beginning with the letter--- NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF beginswith[c] %@", alphabet]; NSArray *states = [listOfStates filteredArrayUsingPredicate:predicate]; //---return the number of states beginning with the letter--- return [states count]; }

Here, you use an NSPredicate object to extract all the states beginning with a particular alphabet:

//---get all states beginning with the letter--- NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF beginswith[c] %@", alphabet]; NSArray *states = [listOfStates filteredArrayUsingPredicate:predicate];

Figure 1. Displaying the 50 States Grouped Alphabetically: This screenshot shows the Table View displaying the states in sections.

The size of the states object indicates the number of states beginning with that particular character, and hence the number of rows for that particular section.

To ensure that the correct state (or states) goes into each section, modify the tableView:cellForRowAtIndexPath: method as follows:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; } //---get the letter in the current section--- NSString *alphabet = [stateIndex objectAtIndex:[indexPath section]]; //---get all states beginning with the letter--- NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF beginswith[c] %@", alphabet]; NSArray *states = [listOfStates filteredArrayUsingPredicate:predicate]; if ([states count]>0) { //---extract the relevant state from the states object--- NSString *cellValue = [states objectAtIndex:indexPath.row]; cell.textLabel.text = cellValue; UIImage *image = [[UIImage imageNamed:@"USA.jpeg"] _imageScaledToSize:CGSizeMake(30.0f, 32.0f) interpolationQuality:1]; cell.imageView.image = image; cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton; } return cell; }

Essentially, you did the same thing as you did in the tableView:numberOfRowsInSection: method. In this case, instead of returning the size of the states object, you extracted the relevant state and used it to populate the Table View cell object. Finally, release the stateIndex object in the dealloc method:

- (void)dealloc { [self.detailsViewController release]; [listOfStates release]; [stateIndex release]; [super dealloc]; }

That's it! Press Command-R to test the application on the iPhone Simulator. Figure 1 shows the Table View displaying the states in sections.

Displaying an Index

Figure 2. Displaying an Index to the Right Side of the Screen: This screenshot shows the Table View displaying the index.
If you have a large number of rows displayed in the Table View, scrolling through them can be quite laborious. Instead of asking the user to scroll from the top to the bottom, it would be helpful to offer a way to jump directly to a particular section. By using an index, you can enable the Table View to do just that. In this example, you have grouped the various states alphabetically and, hence, it would logical to use the alphabet as the index.

The Table View displays the index on the right side of the screen. The user employs the index, which very useful for large number of rows, to jump directly to a section.

Displaying the index in the Table View is very easy: just implement the sectionIndexTitlesForTableView: method and return an array containing the index:

//---set the index for the table--- - (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView { return stateIndex; }

In this case, you simply return the stateIndex object. Press Command-R to test the application on the iPhone Simulator. Figure 2 shows the Table View displaying the index.



Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap