`

[iOS开发教程-5]Create Indexed UITableView

    博客分类:
  • iOS
 
阅读更多

http://www.iphonedevcentral.com/indexed-uitableview-tutorial/

 

Tackling that handy index on the right side of table views is really not that complicated. In fact, it only requires that you implement two methods. In this tutorial, I’m going to take you step-by-step on how to wire it all together.

Indexed Table 2

 

Prerequisites

If you were able to follow my previous  tutorials , you’re going to be just fine with this one.  I assume that you have  iPhone SDK 3.x   downloaded and installed, know how to create an empty project and files in Xcode and know a thing or two about Objective-C and Cocoa touch. While I am using iPhone SDK 3.2 Beta, I compiled this project against version 3.1.3, which is the current live version.

Let’s get started!

1 .Set up your project

In Xcode, go to  File -> New Project   and choose  Navigation-based Application   from the iPhone OS tab. Name the application  IndexedTable . At this point, you should have a runnable app with an empty table in it.

2. Create a data source

Instead of hardcoding a bunch of values, country names and whatnot, let’s create a simple method that will generate a bunch of strings from the letters of the alphabet so that our UITableView has something to work with.

Create a new class called  DataGenerator . Right-click on the  Classes   group in the project browser and choose  New File . Let the file be an  Objective-C class   (subclass of NSObject) and name it  DataGenerator . This class will only have one static method (for now) that will simply return an array of words from letters. As such, we’ll name it  wordsFromLetters .

In  DataGenerator.h , insert the following code:

@interface DataGenerator : NSObject {
}
 
+ (NSArray *) wordsFromLetters;
 
@end

Now, let’s implement this method. Open  DataGenerator.m   and put this code in it:

@implementation DataGenerator
 
#define WORD_LENGTH 5
 
static NSString *letters = @"abcdefghijklmnopqrstuvwxyz";
 
+ (NSArray *) wordsFromLetters {
    NSMutableArray *content = [NSMutableArray new];
 
    for (int i = 0; i < [letters length]; i++ ) {
        NSMutableDictionary *row = [[[NSMutableDictionary alloc] init] autorelease];
        char currentWord[WORD_LENGTH + 1];
        NSMutableArray *words = [[[NSMutableArray alloc] init] autorelease];
 
        for (int j = 0; j < WORD_LENGTH; j++ ) {
            if (j == 0) {
                currentWord[j] = toupper([letters characterAtIndex:i]);
            }
            else {
                currentWord[j] = [letters characterAtIndex:i];
            }
            currentWord[j+1] = '\0';
            [words addObject:[NSString stringWithCString:currentWord encoding:NSASCIIStringEncoding]];
        }
        char currentLetter[2] = { toupper([letters characterAtIndex:i]), '\0'};
        [row setValue:[NSString stringWithCString:currentLetter encoding:NSASCIIStringEncoding]
               forKey:@"headerTitle"];
        [row setValue:words forKey:@"rowValues"];
        [content addObject:row];
    }
 
    return content;
}
 
@end

 

I’m not going to spend a whole of time explaining what’s going on here because this tutorial is really about adding an index bar to your UITableView. But let’s briefly talk what’s it all about. This method loops through an array letters one-by-one. For each letter it then generates a bunch of words to fill up our content. The final structure of the NSArray we’re returning is going to look something like this:

NSArray =>

  1. NSDictionary
    • headerTitle   => ‘A’
    • rowValues   => {”A”, “Aa”, “Aaa”, “Aaaa”}
  2. NSDictionary
    • headerTitle   => ‘B’
    • rowValues   => {”B”, “Bb”, “Bbb”, “Bbbb”}
  3. etc.

You’ll see how we’re using this array later on. Also note that this list is implicitly ordered.

3. Fill in UITableView with values from  DataGenerator

Next we’re going to populate the currently empty table with data we get from our data generator. Open  RootViewController.h   and add these two instance variables to the class:

#import "DataGenerator.h"
 
@interface RootViewController : UITableViewController {
    NSArray *content;
    NSArray *indices;
}

content   will hold our array of dictionaries while  indices   will hold all initial letters for each word in the list. Let's fill those up. Open  RootViewController.m implementation file and override the method  viewDidLoad   with the following:

- (void)viewDidLoad {
    [super viewDidLoad];
    content = [DataGenerator wordsFromLetters];
    indices = [[content valueForKey:@"headerTitle"] retain];
}

You can see that we're using  [DataGenerator wordsFromLetters]   to simply fill in the  content   variable. The second line of that method returns all keys from the dictionaries in  content   as an array. So  indices   now holds all letters of the alphabet.

We next override the two methods that tell our UITableView how many sections it has and how many rows there are in each section.

// Customize the number of sections in the table view.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return [content count];
}
 
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [[[content objectAtIndex:section] objectForKey:@"rowValues"] count] ;
}

The number of sections is equal to the number of letters in our list and the number of rows of each section is equal to the count of each array under its corresponding letter.

Finally, we implement cellForRowAtIndexPath   so that it displays words from our list in the table. We handle headers for sections in  titleForHeaderInSection . This method queries our content at a particular section and demands a  headerTitle   to be returned as header of that section.

// Customize the appearance of table view cells.
- (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];
    }
    cell.textLabel.text = [[[content objectAtIndex:indexPath.section] objectForKey:@"rowValues"]
                           objectAtIndex:indexPath.row];
 
    return cell;
}
 

You should be able to run your app now (CMD + R) and see something like this:

Indexed Table 01

4. Add index to the table

There is nothing new in what we've done so far. We simply filled in a UITableView with some data. We're now ready to add our index to it. For that, we'll need to implement two methods:  sectionIndexTitlesForTableView   and  sectionForSectionIndexTitle .

Add this code to  RootViewController.m :

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
    return [content valueForKey:@"headerTitle"];
}
 
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
    return [indices indexOfObject:title];
}
 

sectionIndexTitlesForTableView:   In order to properly render the index, the UITableView needs to know all index titles to display. This method returns an array of strings containing all indices. In our case, A, B, C, D, etc.

sectionForSectionIndexTitle:   When you start scrolling through the index, the table needs to know how far down/up to scroll so that the letter you're touching corresponds the appropriate section in the table. This method returns an index value (integer) of the section you're currently touching in the index.

One more thing we need to do before we run our app is to add titles to each section header in UITableView.

- (NSString *)tableView:(UITableView *)aTableView titleForHeaderInSection:(NSInteger)section {
	return [[content objectAtIndex:section] objectForKey:@"headerTitle"];
 
}

5. Run your app

If everything went well, you should now be able to run your app and see the final product. You'll see the index on the right and scrolling over it will scroll the table appropriately.

indexedtable02

Conclusion

Voilà! That wasn't that hard was it? The main get-away from this tutorial are the two methods you need to implement in order for the index to show up and function properly:  sectionIndexTitlesForTableView : and  sectionForSectionIndexTitle :. In the next tutorial, we'll cover how to add a search bar to this table.

The complete source code for this tutorial can be found here: Indexed UITableView

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics