简体   繁体   中英

How to populate, Expandable TableView with two NSMutableArray using objective-c

I am using an Expandable UITableview created by Tom Fewster. I want to tweak the example using two NSMutableArray s, which is a scenario whereby if someone wants to populate an expandable/collapse treeview table from webservice json data would want to achieve. So since in his example the GroupCell does not have an array of, I am wondering how can I do it? Please bear in mind that my Objective-C is still rusty hence, I'm asking this question.

With my attempt is only displaying the first ObjectAtIndex:indexPath:0 for the group.

I want to be able to populate the table and get output like this;

  • Group A
    • Row 1a
    • Row 2a
    • Row 3a
  • Group B
    • Row 1b
    • Row 2b
  • Group C
    • Row 1c
    • Row 2c
    • Row 3c and so on.

You may use JSON data as well to explain your answer if you understand it better that way.

Here i want to populate the table with JSON data so the GroupCell show class_name and rowCell show subject_name. This is the console of what I am parsing from the JSON web-service;

(
    {
    "class_id" = 70;
    "class_name" = Kano;
    subject =         (

            "subject_id" = 159;
            "subject_name" = "Kano Class";
        }
    );
},
    {
    "alarm_cnt" = 0;

    "class_id" = 71;
    "class_name" = Lagos;
    subject =         (

            "subject_id" = 160;
            "subject_name" = "Lagos Class";
        }
    );
},
    {
    "alarm_cnt" = 3;
    "class_id" = 73;
    "class_name" = Nasarawa;
    subject =         (

            "subject_id" = 208;
            "subject_name" = "DOMA Class";
        },

            "subject_id" = 207;
            "subject_name" = "EGGON Class";
        },

            "subject_id" = 206;
            "subject_name" = "KARU Class";
        },

            "subject_id" = 209;
            "subject_name" = "LAFIA Class";
        },

            "subject_id" = 161;
            "subject_name" = "Nasarawa State Class";
        }
    );
},
    {
    "alarm_cnt" = 2;
    "class_id" = 72;
    "class_name" = Rivers;
    subject =         (

            "subject_id" = 162;
            "subject_name" = "Rivers Class";
        }
    );
}

)

I have tried this here is my snippet

- (UITableViewCell *)tableView:(ExpandableTableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

{ static NSString *CellIdentifier = @"RowCell";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

NSDictionary *d=[_sitesJson objectAtIndex:0] ;
NSArray *arr=[d valueForKey:@"subject_name"];
NSDictionary *subitems = [arr objectAtIndex:0];
NSLog(@"Subitems: %@", subitems);
NSString *siteName = [NSString stringWithFormat:@"%@",subitems];
cell.textLabel.text =siteName;
//}
NSLog(@"Row Cell: %@", cell.textLabel.text);
// just change the cells background color to indicate group separation
cell.backgroundView = [[UIView alloc] initWithFrame:CGRectZero];
cell.backgroundView.backgroundColor = [UIColor colorWithRed:232.0/255.0 green:243.0/255.0 blue:1.0 alpha:1.0];

return cell;

}

- (UITableViewCell *)tableView:(ExpandableTableView *)tableView cellForGroupInSection:(NSUInteger)section

{ static NSString *CellIdentifier = @"GroupCell";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
UILabel *textLabel = (UILabel *)[cell viewWithTag:2];
NSDictionary *d2 = [_regionsJson objectAtIndex:0];
NSArray *arr2 = [d2 objectForKey:@"class_name"];
NSString *regions = [[arr2 objectAtIndex:section]objectAtIndex:0];
textLabel.textColor  = [UIColor whiteColor];
textLabel.text = [NSString stringWithFormat: @"%@ (%d)", regions, (int)[self tableView:tableView numberOfRowsInSection:section]];
NSLog(@"Group cell label: %@", textLabel.text);

// We add a custom accessory view to indicate expanded and colapsed sections
cell.accessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"ExpandableAccessoryView"] highlightedImage:[UIImage imageNamed:@"ExpandableAccessoryView"]];
UIView *accessoryView = cell.accessoryView;
if ([[tableView indexesForExpandedSections] containsIndex:section]) {
    accessoryView.transform = CGAffineTransformMakeRotation(M_PI);
} else {
    accessoryView.transform = CGAffineTransformMakeRotation(0);
}
return cell;

}

He, just need to update one single method little bit way

- (UITableViewCell *)tableView:(ExpandableTableView *)tableView cellForGroupInSection:(NSUInteger)section
{
    static NSString *CellIdentifier = @"GroupCell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    NSIndexPath *indexPath;
    NSString *regions = [[_dataGroup objectAtIndex:section]objectAtIndex:0];
    cell.textLabel.text = [NSString stringWithFormat: @"%@ ", regions];

    // We add a custom accessory view to indicate expanded and colapsed sections
    cell.accessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"ExpandableAccessoryView"] highlightedImage:[UIImage imageNamed:@"ExpandableAccessoryView"]];
    UIView *accessoryView = cell.accessoryView;
    if ([[tableView indexesForExpandedSections] containsIndex:section]) {
        accessoryView.transform = CGAffineTransformMakeRotation(M_PI);
    } else {
        accessoryView.transform = CGAffineTransformMakeRotation(0);
    }
    return cell; 
}

May help it you.

HTH, Enjoy Coding !!

I think you need to create a TableView which will have a sections array, and each sections row will be populated using the corresponding sections array. Tapping on a section will expand it and it's all rows will be visible.

To meet your requirements, you could follow the below steps as well -

1) Your modal should have a array for sections. The sections array will contain the sections objects, name of the section and corresponding array of the rows.

2) Implement the data source methods of the table view like

- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView

{
    return [section count];
} 

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section

{
    return 50; // sections height
} 

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    return nil;
}

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
    return nil;
}

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{

    UIView *view = [[[UIView alloc] initWithFrame:CGRectMake(0 , 0, tableView.frame.size.width , 50)] autorelease];

    [view setBackgroundColor:[UIColor redColor]];
    view.layer.masksToBounds = YES;


    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(5 , 2 , view.frame.size.width - 10 , view.frame.size.height - 3)];
    label.text = ((SectionObject *)[section objectAtIndex:indexPath.section]).sectionName;
    label.backgroundColor = [UIColor clearColor];
    label.textAlignment = NSTextAlignmentLeft;
    label.textColor = [UIColor WwhiteColor];
    label.clipsToBounds = YES;
    label.font = [UIFont fontWithName:@"HelveticaNeue-CondensedBold" size:14.0f];
    label.layer.masksToBounds = YES;

    UIImageView *arrowImage = [[UIImageView alloc] initWithFrame:CGRectMake(view.frame.size.width - 30, 0, 17 , 17)];
    [arrowImage setCenter:CGPointMake(arrowImage.center.x , (view.frame.size.height/2) ) ];

    if(section == self.m_currentSelectedSection)
        [arrowImage setImage:self.m_upArrowImage];
    else
        [arrowImage setImage:self.m_downArrowImage];

    UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, view.frame.size.width, view.frame.size.height)];
    button.tag = section;
    [button addTarget:self action:@selector(sectionTapped:) forControlEvents:UIControlEventTouchUpInside];
    button.backgroundColor = [UIColor clearColor];

    [view addSubview:label];
    [label release];

    [view addSubview:arrowImage];
    [arrowImage release];

    [view addSubview:button];
    [button release];

    view.clipsToBounds = YES;

    return view;
}



- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    NSInteger count = 0;

    if(self.m_currentSelectedSection == section)
              count = [((SectionObject *)[section objectAtIndex:indexPath.section]).rowArray count];

    return count;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 40.0;
}

- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString * cellId = @"cellIdentifier";

    UITableViewCell *cell = nil;

    cell = (UITableViewCell *) [tableView dequeueReusableCellWithIdentifier:cellId];

    if(cell == nil)
    {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease];
            cell.selectionStyle = UITableViewCellSelectionStyleNone;
    }
    //customize cell
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath:indexPath animated:NO];
}

When ever any section will be tapped following event will be invoked

- (void) sectionTapped:(UIButton *)button
{
    self.m_currentSelectedSection = button.tag;
    [self performSelector:@selector(refreshView) withObject:nil afterDelay:POINT_ONE_SECOND];
    if(m_winnerSlotList->at(self.m_currentSelectedSection).m_leaderboardList.size())
        [self.m_leaderboardTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:button.tag] atScrollPosition:UITableViewScrollPositionTop animated:YES];

    UIView *baseView = [button superview];
    if(baseView)
    {
        for(int ii = 0 ; ii < [[baseView subviews] count] ; ii++ )
        {
            UIView *anyView = [[baseView subviews] objectAtIndex:ii];
            if([anyView isKindOfClass:[UIImageView class]])
                [(UIImageView *)anyView setImage:self.m_upArrowImage];
        }
    }
}

Initialize self.m_currentSelectedSection = 0 , for the first time, this will show the rows for 0th section. As any section is tapped it's rows will be visible (corresponding section rows will expand) and the rows for the previous selected section will be hidden(previous section rows will collapse).

If you need to show more than one section as expanded than you need to keep track of all the section whether a section is expanded or not and accordingly load show/ hide the cells for the corresponding section.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM