expandable list view in iOS

I need to create expandable list view in my iOS app, ie. if you tap on a cell, it should expand to give more cells. I'm following the example given on this link: Toggle showing/hiding child table cells iOS The code for the implementation file is given here too: http://pastie.org/7756763

However, in the example above the arrays are fixed. I have a sqlite database where I store tasks and their start dates, among other things. I need to create an expandable view where the different rows are the different start dates and when I tap on a date, it should give the tasks for that date. Here's the code:

- (void)viewDidLoad
{
    [super viewDidLoad];
    allDates = [[NSMutableArray alloc]init];

    self.date = [[NSMutableArray alloc] initWithObjects: nil];
   // self.date = [[NSMutableArray alloc]init];
    self.listOfSections_DataSource = [[NSMutableArray alloc]initWithObjects:nil];

    sqlite3_stmt *statement;
    const char *dbpath = [mDatabasePath UTF8String];
    if (sqlite3_open(dbpath,&mDiary)== SQLITE_OK) {
        NSString *selectSQL = [NSString stringWithFormat:@"SELECT * FROM TODO"];
        const char *query_stmt = [selectSQL UTF8String];
        if (sqlite3_prepare_v2(mDiary,
                               query_stmt, -1, &statement, NULL) == SQLITE_OK)
        {
                    while(sqlite3_step(statement) == SQLITE_ROW)
            {
                tempTaskName = [[NSString alloc]initWithUTF8String:(const char *) sqlite3_column_text(statement, 2)];
                [allDates addObject:[[NSString alloc]initWithUTF8String:(const char *) sqlite3_column_text(statement, 0)]];

                [self.date addObject:tempTaskName];


            }

    }
    sqlite3_finalize(statement);
}
sqlite3_close(mDiary);

NSLog(@"%i",[allDates count]);

        for(int x = 0;x < [allDates count];x++)
        {
            if (sqlite3_open(dbpath,&mDiary)== SQLITE_OK) {
                NSString *selectSQL = [NSString stringWithFormat:@"SELECT * FROM TODO"];
                const char *query_stmt = [selectSQL UTF8String];

                if (sqlite3_prepare_v2(mDiary,
                                       query_stmt, -1, &statement, NULL) == SQLITE_OK){
            temp = [[NSMutableArray alloc]init];
            while(sqlite3_step(statement) == SQLITE_ROW)
            {
                tempTaskName = [[NSString alloc]initWithUTF8String:(const char *) sqlite3_column_text(statement, 2)];
                NSLog(@"%@",tempTaskName);
               // [allDates addObject:[[NSString alloc]initWithUTF8String:(const char *) sqlite3_column_text(statement, 0)]];
                if([[[NSString alloc]initWithUTF8String:(const char *) sqlite3_column_text(statement, 0)] isEqualToString:allDates[x]])
                {
                    [self.temp addObject:tempTaskName];
                }




            }
            NSLog(@"task name%@",temp);
            [listOfSections_DataSource addObject:temp];

                } sqlite3_finalize(statement);
            }
            sqlite3_close(mDiary);
        }

    //[self.listOfSections_DataSource addObject:allDates];

   NSMutableArray *emptyArray = [[NSMutableArray alloc]init];
   listOfSections = [[NSMutableArray alloc]init];
    for (int i = 0;i<[allDates count]; i++) {
        [listOfSections addObject:emptyArray];
    }  
    self.selectedSection = -1;
    self.selectedSectionTail = -1;
}

the table view methods are:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {


    return [listOfSections_DataSource count];


}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    if(selectedSection !=section)
        return 1;
    else{
        NSArray *array = [listOfSections objectAtIndex:section];

        return [array count];
    }

}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"cell";

    if(self.selectedSection == indexPath.section){//this is just to check to see if this section is the one we touched

        UITableViewCell *cell =  [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil)
        {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        }

        NSArray *myArray = [listOfSections_DataSource objectAtIndex:indexPath.section];//this now contains your cities
        NSString* myString = [myArray objectAtIndex:indexPath.row]; // get city for that row, under the state

        cell.textLabel.text = myString;
        return cell;
    }
    else{//THIS IS going to happen the first time
        UITableViewCell *cell =  [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil)
        {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        }

            cell.textLabel.text = @"more";

        return cell;
    }
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {


    UITableViewCell * cell = [tableView cellForRowAtIndexPath:indexPath];

    //check to see if the cell is for exapnding or for selection
    if([cell.textLabel.text isEqualToString:@"more"]){ // this means we need to expand

        listOfSections = [[NSMutableArray alloc]init];
        //setting up the list of section with empty arrays

        NSMutableArray *emptyArray = [[NSMutableArray alloc]init];
        for (int i = 0;i<[allDates count]; i++) {
            [listOfSections addObject:emptyArray];
        }

        //Add array of tasks here
        [listOfSections replaceObjectAtIndex:indexPath.section withObject:[listOfSections_DataSource objectAtIndex:indexPath.section]];


        int tapedRow = [indexPath section];

        self.selectedSection = tapedRow;

        NSMutableIndexSet *myIndexSet = [[NSMutableIndexSet alloc]init];
        [myIndexSet addIndex:selectedSection];
        [myIndexSet addIndex:selectedSectionTail];

        // Updating section in the tableview
        if(selectedSectionTail!=-1)
            [taskTable reloadSections:(NSIndexSet*)myIndexSet withRowAnimation:UITableViewRowAnimationFade];
        else {
            [taskTable reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:
             UITableViewRowAnimationFade];
        }
        //[taskTable reloadData];
    }
    else{
    }
    selectedSectionTail = selectedSection;
}

The problem here is that: 1. No. of sections that shows on screen is correct but when the first cell is tapped, it disappears. 2. the list doesn't get expanded when any of the cells is tapped.

Please can anyone help me out? Thanks..

Answers


This sample may be what you're looking for: http://developer.apple.com/library/ios/#samplecode/TableViewUpdates/Introduction/Intro.html

The sample pulls from static data, but you should be able to update it to use dynamic data from your DB, and also to give the tasks for a date, etc.


JKExpandTableView is an open source library implementing an expandable table view (subclass of UITableView) and should help you: http://jackkwok.github.io/JKExpandTableView/

Check out the sample app.


Need Your Help

Send a message from Javascript running in a browser to a windows batch file

javascript windows batch-file

Due to an architecture I must work with that likely breaks a lot of very good software design rules, I need to send a message from some javascript code running in a web browser to a windows batch f...

Error calling SetAccessor when binding C++ functions to V8

javascript c++ v8

I'm following the Embedder's Guide for V8 in order to call C++ from JavaScript. I am encountering an error with setting accessors. Specifically, the following code does not compile for me under the