How to create UITableView Index for large datasets
I have gone down the rabbit hole of indexed, sectioned, tableviews and have been taken on a ride that has made me want to damage alot of valuable objects in my room... I am hoping with one last clear concise question that someone will be able to help me solve this on going struggle.
Im going to start from the beginning so as not to confuse anyeon that offers their help, I think its easier that way and hopefully someone can post some fairly decent examples for me to read/use, as in previous questions I think I have supplied to much detail and confused everyone where the request is actually simple.. its just the implementation is drawn out and dependant on what data you have coming in and how.
Okay here we go.
I have a UITableView which when opened queries my database for a list of car manufactures, I parse the XML that comes in and am left with a unsorted list of car manufactures, I then pass this NSArray over to a custom method that then sortes it A-Z.
- (IBAction)startSortingTheArray:(NSMutableArray *)arrayData
{
//Sort incoming array alphabetically
[self setSortedArray:[arrayData sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)]];
From here I would like to know how to make a Indexed UITableview for Index Scrolling of a large database.. <<---- This is my question
Heres what I know, From this point I need to create an array of letters that represent the letters of the alp开发者_StackOverflow中文版habet thats found in my data (i.e.) first letter of each value in my sorted array. I also need to create an NSDictionary with my sorted arrays split into sections withing this dictionary.
From there I need to update some of my UItableview delegate methods so that they can handle the NSDictionary and sections etc.. From there I need to pass the values in my NSDictionary over to my UItableviewcell labels...
In all previous attempts I have gotten to the point where I have everything but actually being able to display the data into the tableview cells, but because its been put together by reading several different tutorials its just not working. So I figured now that I actually kinda know what needs to happen maybe someone will be kind enough to share their code of a similar problem that I will be able to learn from and hopefully learn how to actually do this...
I would like to thank anyone that has helped me so far and anyone who is about to help me in the future :P I will be sure to post my final solution with comments to hopefully prevent this from happening to anyone else in the future! I cannot help but feel a slight amount of hatred towards apple for this pickle of an implementation.
Honda,
Honda,
Honda,
Honda,
Honda,
Honda,
Honda,
Mazda,
Mazda,
Mitsubishi,
Mitsubishi,
Mitsubishi,
Mitsubishi,
Mitsubishi,
Mitsubishi,
Nissan,
Nissan,
Nissan,
Nissan,
Nissan,
Nissan,
Nissan,
Toyota,
Toyota,
Toyota
From reading your question, it sounds like you want to have a sectioned UITableView
based on a large database. How many sections are you thinking? It can handle as many as you want, but there are some features which you will not be able to use, like the index
-ing may not be great if you have 100+ sections. (In fact, I think there might be a limit on this, but I'm not sure.)
The easiest thing to do in this case would be to have an array of arrays. The array would hold an array for each section. So it would be something like:
@interface myTableView: UITableViewController {
NSMutableArray * arrayOfSection;
NSMutableArray * sectionHeaders;
}
@implementation myTableView
// Note I will assume that arrayData contains only NSStrings.
- (void)sortSectionsWithArray:(NSMutableArray *)arrayData; {
NSMutableArray * alphabet = [[NSMutableArray alloc] initWithObjects:@"A", @"B", ..., @"Y", @"Z", nil];
NSString * firstLetter;
for(NSString * string in arrayData){
firstLetter = [string substringToIndex:1];
for(NSString * sectionString in alphabet){
if([firstLetter isEqualToString:sectionString]){
[alphabet removeObject:sectionString];
break;
}
}
}
// Note that whatever is left over are the letters of the alphabet that are NOT section headers, as we removed the section headers strings.
// Therefore, if we remove the letters stored in the alphabet array, we have the remaining section headers!
if(sectionHeaders){
[sectionHeaders release];
}
sectionHeaders = [[NSMutableArray alloc] initWithObjects:@"A", @"B", ..., @"Y", @"Z", nil];
for(NSString * string in sectionHeaders){
for(NSString * sectionString in alphabet){
if([string isEqualToString:sectionString]){
[sectionHeaders removeObject:string];
break;
}
}
}
}
// Assume that the array below is your input array:
// NSArray * arrayData = [[NSArray alloc] initWithObjects:@"Honda", @"Honda", @"Mazda", @"Mazda", @"Mitsubishi", @"Mitsubishi", @"Nissan", @"Nissan", @"Toyota", @"Toyota", nil];
- (void)startSortingTheArray:(NSMutableArray *)arrayData; {
if(arrayOfSection){
[arrayOfSection release];
}
arrayOfSection = [[NSMutableArray alloc] initWithCapacity:[sectionHeaders count]];
NSMutableArray * section;
for(NSString * string in sectionHeaders){
section = [[NSMutableArray alloc] init];
for(NSString * dataString in arrayData){
if([string isEqualToString:[dataString substringToIndex:1]]){
[section addObject:dataString];
}
}
[arrayOfSection addObject:section];
[section release];
}
}
Then, in your UITableViewDelegate
methods, use:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView; {
return [arrayOfSection count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section; {
return [[arrayOfSection objectAtIndex:section] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath; {
static NSString * CellIdentifier = @"TableViewCell";
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
[[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:self options:nil];
}
// Set model saved in arrayOfSection by using: [[arrayOfSection objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath; {
// What you want the view controller to do when a row is selected.
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section; {
return [sectionHeaders objectAtIndex:section];
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView; {
return sectionHeaders;
}
- (void)dealloc; {
[arrayOfSection release];
[sectionHeaders release];
[super dealloc];
}
Hope that Helps!
精彩评论