Search code examples
objective-ciosuitableviewnsarraynsdictionary

Create index for UITableView from an NSArray


I've read that the best way of creating an index (the a-z at the side of a uitableview) is to set up an array of nsdictionaries, where each dictionary corresponds to a section, and a rowValue key contains an array of the rows.

NSDictionary
    headerTitle => ‘A’
    rowValues => {”Aardvark”, “Ape”, “Aquaman”}
NSDictionary
    headerTitle => ‘B’
    rowValues => {”Bat”, “Boot”, “Bubbles”} etc

But how can this be created from an array of all the row titles - {”Aardvark”, “Ape”, “Aquaman”, ”Bat”, “Boot”, “Bubbles”, "Cat", "Cabbage" etc} ...?


Solution

  • #pragma mark -
    #pragma mark View lifecycle
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        NSMutableArray *temp = [[NSMutableArray alloc] init];
        NSMutableArray *temp2 = [[NSMutableArray alloc] init];
        for(int i = 0; i < tableListArray.count; i++)
        {
            NSString *string = [tableListArray objectAtIndex:i];
            NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
            [dict setObject:string forKey:@"Name"];
            [dict setObject:[NSNumber numberWithInt:i] forKey:@"ID"];
            NSString *firstString = [string substringToIndex:1];
            if([temp2 containsObject:firstString] == NO || temp2.count == 0)
            {
                if(temp2.count != 0)
                {
                    [temp addObject:temp2];
                    [temp2 release];
                    temp2 = [[NSMutableArray alloc] init];
                }
                [temp2 addObject:firstString];
            }
            [temp2 addObject:dict];
            [dict release];
        }
        [temp addObject:temp2];
        detailListArray = [[NSArray alloc] initWithArray:temp];
        [temp release];
        [temp2 release];
    }
    
    #pragma mark -
    #pragma mark Table view data source
    - (NSInteger)tableView:(UITableView *)tableView 
    sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index
    {
        int i = 0;
        for(NSArray *array in detailListArray)
        {
            NSString *string = [array objectAtIndex:0];
            if([string compare:title] == NSOrderedSame)
                break;
            i++;
        }
        return i;
    }
    
    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
    {
        return detailListArray.count;
    }
    
    - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
    {
        NSArray *array = [detailListArray objectAtIndex:section];
        return [array objectAtIndex:0];
    }
    
    - (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView 
    {
        NSMutableArray *titleArray = [NSMutableArray array];
        [titleArray addObject:@"A"];
        [titleArray addObject:@"B"];
        [titleArray addObject:@"C"];
        [titleArray addObject:@"D"];
        [titleArray addObject:@"E"];
        [titleArray addObject:@"F"];
        [titleArray addObject:@"G"];
        [titleArray addObject:@"H"];
        [titleArray addObject:@"I"];
        [titleArray addObject:@"J"];
        [titleArray addObject:@"K"];
        [titleArray addObject:@"L"];
        [titleArray addObject:@"M"];
        [titleArray addObject:@"N"];
        [titleArray addObject:@"O"];
        [titleArray addObject:@"P"];
        [titleArray addObject:@"Q"];
        [titleArray addObject:@"R"];
        [titleArray addObject:@"S"];
        [titleArray addObject:@"T"];
        [titleArray addObject:@"U"];
        [titleArray addObject:@"V"];
        [titleArray addObject:@"W"];
        [titleArray addObject:@"X"];
        [titleArray addObject:@"Y"];
        [titleArray addObject:@"Z"];
        return titleArray;
    }
    
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        NSArray *array = [detailListArray objectAtIndex:section];
        return (array.count - 1);
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        UITableViewCell *cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                                        reuseIdentifier:@"CELL"] autorelease];
        NSArray *array = [detailListArray objectAtIndex:indexPath.section];
        NSDictionary *dict = [array objectAtIndex:indexPath.row + 1];
        cell.textLabel.text = [dict objectForKey:@"Name"];
        return cell;
    }
    
    #pragma mark -
    #pragma mark Table view delegate
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        NSArray *array = [detailListArray objectAtIndex:indexPath.section];
        NSDictionary *dict = [array objectAtIndex:indexPath.row + 1];
        int entryID = [[dict objectForKey:@"ID"] intValue];
         // Do what ever you want to do with the selected row here....
    }
    

    This is the code that I have used in one of the recent projects.