How to create a multilevel UITableView upto n level in Objective-c - ios

I want to create a generic UITableView expand and collapse so that it can be bind with array of arrays/dictionary to multilevel.
Number of levels will be defined on run time. Please help, I am working in Objective-C.

Try this code. Worked for me as per my requirement.
------ To expand the rows ------
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSDictionary * d = [self.arForTable objectAtIndex:indexPath.row];
if([d valueForKey:#"Objects"]) {
NSArray * ar = [d valueForKey:#"Objects"];
BOOL isAlreadyInserted = NO;
for(NSDictionary * dInner in ar){
NSInteger index = [self.arForTable indexOfObjectIdenticalTo:dInner];
isAlreadyInserted = (index > 0 && index != NSIntegerMax);
if(isAlreadyInserted) break;
}
if(isAlreadyInserted) {
[self miniMizeThisRows:ar];
}
else {
NSUInteger count = indexPath.row+1;
NSMutableArray * arCells = [NSMutableArray array];
for(NSDictionary * dInner in ar) {
[arCells addObject:[NSIndexPath indexPathForRow:count inSection:0]];
[self.arForTable insertObject:dInner atIndex:count++];
}
[tableView insertRowsAtIndexPaths:arCells withRowAnimation:UITableViewRowAnimationFade];
[tableView beginUpdates];
[tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationNone];
[tableView endUpdates];
}
}
}
------ To minimize the rows ------
-(void)miniMizeThisRows:(NSArray *)ar{
for(NSDictionary * dInner in ar ) {
NSUInteger indexToRemove = [self.arForTable indexOfObjectIdenticalTo:dInner];
NSArray * arInner = [dInner valueForKey:#"Objects"];
if(arInner && [arInner count] > 0){
[self miniMizeThisRows:arInner];
}
if([self.arForTable indexOfObjectIdenticalTo:dInner] != NSNotFound) {
[self.arForTable removeObjectIdenticalTo:dInner];
[self.mainTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:indexToRemove inSection:0]] withRowAnimation:UITableViewRowAnimationFade];
[self.mainTableView beginUpdates];
[self.mainTableView reloadRowsAtIndexPaths:#[[NSIndexPath indexPathForRow:indexToRemove-1 inSection:0]] withRowAnimation:UITableViewRowAnimationFade];
[self.mainTableView endUpdates];
}
}
}

Related

Slide out side bar with sub categories

I am using SWRevealViewController.
These are some rows in table view. Each row opens a new view.
Now I want to show some sub categories/rows on click of Services and vice versa.
The sub categories will be like Designing, Development, Applications etc.
and each of this sub category opens different view.
I am using only 1 section. Any ideas?
You can use UIPopoverContoller containing UITableView for subCategories
Here is the link for UIPopover https://github.com/alvises/FPPopover
As UIPopover is for ipad so in iphone u will have import thirdparty library mention above.
you can use these MMDrawerController containing UITableview for Slide out side bar with sub categories,it has very good animation styles for side bar..
https://github.com/mutualmobile/MMDrawerController
i hope it helps..
Use following steps to implement expandable 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=[[self.arForTable objectAtIndex:indexPath.row] valueForKey:#"name"];
[cell setIndentationLevel:[[[self.arForTable objectAtIndex:indexPath.row] valueForKey:#"level"] intValue]];
return cell;
}
This is the method TableView DidSelectRow Method for expanding and collapsing rows
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSDictionary *d=[self.arForTable objectAtIndex:indexPath.row];
if([d valueForKey:#"Objects"]) {
NSArray *ar=[d valueForKey:#"Objects"];
BOOL isAlreadyInserted=NO;
for(NSDictionary *dInner in ar ){
NSInteger index=[self.arForTable indexOfObjectIdenticalTo:dInner];
isAlreadyInserted=(index>0 && index!=NSIntegerMax);
if(isAlreadyInserted) break;
}
if(isAlreadyInserted) {
[self miniMizeThisRows:ar];
} else {
NSUInteger count=indexPath.row+1;
NSMutableArray *arCells=[NSMutableArray array];
for(NSDictionary *dInner in ar ) {
[arCells addObject:[NSIndexPath indexPathForRow:count inSection:0]];
[self.arForTable insertObject:dInner atIndex:count++];
}
[tableView insertRowsAtIndexPaths:arCells withRowAnimation:UITableViewRowAnimationLeft];
}
}
}
Method to expand and minimize the cells
(void)miniMizeThisRows:(NSArray*)ar{
for(NSDictionary *dInner in ar ) {
NSUInteger indexToRemove=[self.arForTable indexOfObjectIdenticalTo:dInner];
NSArray *arInner=[dInner valueForKey:#"Objects"];
if(arInner && [arInner count]>0){
[self miniMizeThisRows:arInner];
}
if([self.arForTable indexOfObjectIdenticalTo:dInner]!=NSNotFound) {
[self.arForTable removeObjectIdenticalTo:dInner];
[self.tableView deleteRowsAtIndexPaths:
[NSArray arrayWithObject:[NSIndexPath indexPathForRow:indexToRemove inSection:0]]
withRowAnimation:UITableViewRowAnimationRight];
}
}
}

update UITableView sectionHeaderHeight at time of UIButton click in iOS

Good day! My default tableview sectionHeaderHeight is 56. I want to update it when sectionOpened method gets called.This is the following code:
- (void) sectionOpened : (NSInteger) section
{
sectionHeight = #"YES";
getsection = section;
NSLog(#"Section Clicked: %ld",(long)getsection);
SectionInfo *array = [self.sectionInfoArray objectAtIndex:section];
array.open = YES;
NSInteger count = [array.category.menulist count];
NSMutableArray *indexPathToInsert = [[NSMutableArray alloc] init];
for (NSInteger i = 0; i<count;i++)
{
[indexPathToInsert addObject:[NSIndexPath indexPathForRow:i inSection:section]];
}
NSMutableArray *indexPathsToDelete = [[NSMutableArray alloc] init];
NSInteger previousOpenIndex = self.openSectionIndex;
if (previousOpenIndex != NSNotFound)
{
SectionInfo *sectionArray = [self.sectionInfoArray objectAtIndex:previousOpenIndex];
sectionArray.open = NO;
NSInteger counts = [sectionArray.category.menulist count];
[sectionArray.sectionView toggleButtonPressed:FALSE];
for (NSInteger i = 0; i<counts; i++)
{
[indexPathsToDelete addObject:[NSIndexPath indexPathForRow:i inSection:previousOpenIndex]];
}
}
UITableViewRowAnimation insertAnimation;
UITableViewRowAnimation deleteAnimation;
if (previousOpenIndex == NSNotFound || section < previousOpenIndex)
{
insertAnimation = UITableViewRowAnimationTop;
deleteAnimation = UITableViewRowAnimationBottom;
}
else
{
insertAnimation = UITableViewRowAnimationBottom;
deleteAnimation = UITableViewRowAnimationTop;
}
[menulistTable beginUpdates];
if(section==3 || section==4 || section==5) // this section has cells like submenu of a menu
{
menulistTable.sectionHeaderHeight = 20.0;
[menulistTable reloadSections:[NSIndexSet indexSetWithIndex:section] withRowAnimation:UITableViewRowAnimationNone];
//[menulistTable reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationNone];
}
[menulistTable insertRowsAtIndexPaths:indexPathToInsert withRowAnimation:insertAnimation];
[menulistTable deleteRowsAtIndexPaths:indexPathsToDelete withRowAnimation:deleteAnimation];
[menulistTable endUpdates];
self.openSectionIndex = section;
}
But nothing happening. I also used indexSetWithIndex:0. Whats wrong in the code?
Try like this to change Height:
[menulistTable beginUpdates];
menulistTable.sectionHeaderHeight = 20.0;
[menulistTable endUpdates];
Edited:
Take variable to set SectionHeaderHeight. Then place this code:
[menulistTable beginUpdates];
secHeaderHeight = 20.0;
[menulistTable endUpdates];
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return secHeaderHeight;
}
Hope it will work for you.

Different behavior on UITableView control

There Is this control that I really appreciate: github link the problem is that now I have a situation where when I need to open one row and all the previous ones should close, I can only have one open row at the time.
Since I'm not very experienced with xcode, I need some info on where should I start and the necessary steps to make the code work the way I need right now.
I managed to make some tests but not a viable solution, here is what I have right now:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSInteger row = indexPath.row;
if (indexPath.section == 0) {
NSLog(#"indexPath1 = %i", selectedRow);
NSDictionary *d = [self.firstForTable objectAtIndex:indexPath.row];
if([d valueForKey:#"Objects"]) {
NSArray *ar = [d valueForKey:#"Objects"];
NSUInteger count = indexPath.row +1;
NSMutableArray *arCells = [NSMutableArray array];
for(NSDictionary *dInner in ar ) {
[arCells addObject:[NSIndexPath indexPathForRow:count inSection:0]];
[self.firstForTable insertObject:dInner atIndex:count++];
}
[tableView insertRowsAtIndexPaths:arCells withRowAnimation:UITableViewRowAnimationLeft];
}
else {
NSLog(#"Leave Element:::%# %#|",[d valueForKey:#"name"],[d valueForKey:#"book"]);
}
if (selectedRow == row) {
NSLog(#"selectedRow2 = %i",selectedRow);
NSDictionary *d=[self.firstForTable objectAtIndex:selectedRow];
if([d valueForKey:#"Objects"]) {
NSArray *ar = [d valueForKey:#"Objects"];
[self miniMizeFirstsRows:ar];
}
selectedRow = -1;
return;
}
if (selectedRow >= 0) {
NSLog(#"selectedRow3 = %i",selectedRow);
NSDictionary *d=[self.firstForTable objectAtIndex:selectedRow];
if([d valueForKey:#"Objects"]) {
NSArray *ar = [d valueForKey:#"Objects"];
[self miniMizeFirstsRows:ar];
}
selectedRow = row;
}
selectedRow = row;
[tableView beginUpdates]; [tableView endUpdates];
}
if (indexPath.section == 1) {
NSDictionary *d = [self.secondForTable objectAtIndex:indexPath.row];
if([d valueForKey:#"Objects"]) {
NSArray *ar = [d valueForKey:#"Objects"];
BOOL isAlreadyInserted=NO;
for (NSDictionary *dInner in ar) {
NSInteger index = [self.secondForTable indexOfObjectIdenticalTo:dInner];
isAlreadyInserted = (index > 0 && index != NSIntegerMax);
if (isAlreadyInserted) break;
}
if (isAlreadyInserted) {
[self miniMizeSecondsRows:ar];
}
else {
NSUInteger count = indexPath.row+1;
NSMutableArray *arCells = [NSMutableArray array];
for (NSDictionary *dInner in ar ) {
[arCells addObject:[NSIndexPath indexPathForRow:count inSection:1]];
[self.secondForTable insertObject:dInner atIndex:count++];
}
[tableView insertRowsAtIndexPaths:arCells withRowAnimation:UITableViewRowAnimationLeft];
}
}
else {
NSLog(#"Leave Element:::%# %#|",[d valueForKey:#"name"],[d valueForKey:#"book"]);
}
}
}
Thanks in Advance.
UPDATED: Expandable Rows JSON is your project, with auto-collapse working for all rows.
Also check Expandable Rows, i forked this project to help Novara and improve it. Now working for all sections, except nested rows.
FIRST STEP
Track opened row for each section. Of course this can be done using NSArray of tabOpened for multiple sections.
#interface RootViewController : UITableViewController {
NSInteger tabOpened_1;
NSInteger tabOpened_2;
}
SECOND STEP
Next initialize those with "-1" value, for none opened tab.
- (void)viewDidLoad
{
........
[self.firstForTable addObjectsFromArray:self.firstArray];
tabOpened_1 = -1;
[self.secondForTable addObjectsFromArray:self.secondArray];
tabOpened_2 = -1;
}
THIRD STEP
Change the didSelectRowAtIndexPath
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
if (indexPath.section==0) {
NSDictionary *d=[self.firstForTable objectAtIndex:indexPath.row];
if([d valueForKey:#"produtos"]) {
if (tabOpened_1 == -1) {
NSLog(#"No tab opened in first section");
tabOpened_1 = indexPath.row;
} else if(tabOpened_1 != indexPath.row && tabOpened_1 > indexPath.row){
NSDictionary *d_ = [self.firstForTable objectAtIndex:tabOpened_1];
NSArray *ar_ = [d_ valueForKey:#"produtos"];
[self miniMizeFirstsRows:ar_];
tabOpened_1 = indexPath.row;
}
NSArray *ar=[d valueForKey:#"produtos"];
BOOL isAlreadyInserted=NO;
for(NSDictionary *dInner in ar ){
NSInteger index=[self.firstForTable indexOfObjectIdenticalTo:dInner];
isAlreadyInserted=(index>0 && index!=NSIntegerMax);
if(isAlreadyInserted) break;
}
if(isAlreadyInserted) {
[self miniMizeFirstsRows:ar];
} else {
NSUInteger count=indexPath.row+1;
NSMutableArray *arCells=[NSMutableArray array];
for(NSDictionary *dInner in ar ) {
[arCells addObject:[NSIndexPath indexPathForRow:count inSection:0]];
[self.firstForTable insertObject:dInner atIndex:count++];
}
[tableView insertRowsAtIndexPaths:arCells withRowAnimation:UITableViewRowAnimationLeft];
}
if (tabOpened_1 == -1) {
NSLog(#"No tab opened in first section");
tabOpened_1 = indexPath.row;
} else if(tabOpened_1 != indexPath.row && tabOpened_1 < indexPath.row){
NSDictionary *d_ = [self.firstForTable objectAtIndex:tabOpened_1];
NSArray *ar_ = [d_ valueForKey:#"produtos"];
[self miniMizeFirstsRows:ar_];
tabOpened_1 = indexPath.row - [ar_ count];
tabOpened_1 = (tabOpened_1 < 0) ? indexPath.row : tabOpened_1;
}
} else {
NSLog(#"Leave Element:::%# %#|",[d valueForKey:#"nome"],[d valueForKey:#"numeroConta"]);
}
for (int i=0; i < [[self.rowsPerSection objectAtIndex:indexPath.section] integerValue]; i++) {
NSDictionary *d_ = [self.secondForTable objectAtIndex:i];
NSArray *ar_ = [d_ valueForKey:#"produtos"];
[self miniMizeSecondsRows:ar_];
}
}
if (indexPath.section==1) {
if (tabOpened_2 == -1) {
NSLog(#"No tab opened in second section");
tabOpened_2 = indexPath.row;
} else if(tabOpened_2 != indexPath.row && tabOpened_2 > indexPath.row){
NSDictionary *d_ = [self.secondForTable objectAtIndex:tabOpened_2];
NSArray *ar_ = [d_ valueForKey:#"produtos"];
[self miniMizeSecondsRows:ar_];
tabOpened_2 = indexPath.row;
}
NSDictionary *d=[self.secondForTable objectAtIndex:indexPath.row];
if([d valueForKey:#"produtos"]) {
NSArray *ar=[d valueForKey:#"produtos"];
BOOL isAlreadyInserted=NO;
for(NSDictionary *dInner in ar ){
NSInteger index=[self.secondForTable indexOfObjectIdenticalTo:dInner];
isAlreadyInserted=(index>0 && index!=NSIntegerMax);
if(isAlreadyInserted) break;
}
if(isAlreadyInserted) {
[self miniMizeSecondsRows:ar];
} else {
NSUInteger count=indexPath.row+1;
NSMutableArray *arCells=[NSMutableArray array];
for(NSDictionary *dInner in ar ) {
[arCells addObject:[NSIndexPath indexPathForRow:count inSection:1]];
[self.secondForTable insertObject:dInner atIndex:count++];
}
[tableView insertRowsAtIndexPaths:arCells withRowAnimation:UITableViewRowAnimationLeft];
}
if (tabOpened_2 == -1) {
NSLog(#"No tab opened in second section");
tabOpened_2 = indexPath.row;
} else if(tabOpened_2 != indexPath.row && tabOpened_2 < indexPath.row){
NSDictionary *d_ = [self.secondForTable objectAtIndex:tabOpened_2];
NSArray *ar_ = [d_ valueForKey:#"produtos"];
[self miniMizeSecondsRows:ar_];
tabOpened_2 = indexPath.row - [ar_ count];
tabOpened_2 = (tabOpened_2 < 0) ? indexPath.row : tabOpened_2;
}
} else {
//NSLog(#"Leave Element:::%# %#|",[d valueForKey:#"nome"],[d valueForKey:#"book"]);
}
for (int i=0; i < [[self.rowsPerSection objectAtIndex:indexPath.section] integerValue]; i++) {
NSDictionary *d_ = [self.firstForTable objectAtIndex:i];
NSArray *ar_ = [d_ valueForKey:#"produtos"];
[self miniMizeFirstsRows:ar_];
}
}
}
Is this really necessary for you to use mentioned by you control? If not I can propose you another control.
It is open source and available on github https://github.com/Augustyniak/RATreeView.
RATreeView was written by me and (from what you wrote) it has functionality you need. Its public API is based on UITableView's one so it is really simple to use. It has pretty expanded documentation which will allow you to get all needed information. Linked github's repository contains sample project which shows exactly how to start using it in your own project.
In case you start to use it and have some questions just ask.

Expandable tableview cells

My current tableview expands the cells on click, example:
Parent 0
-Child 1
-Child 2
-Child 3
What I'm struggling to do is, when I expand a cell all the others will close, I'm trying to make sure only one cell Is open at the time. Can you guys give any ideas on how to do it?
Current code for expanding the cell:
- (void)tableView:(UITableView *)tableView1 didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section==0) {
if([d valueForKey:#"produtos"]) {
NSArray *ar=[d valueForKey:#"produtos"];
BOOL isAlreadyInserted=NO;
for(NSDictionary *dInner in ar ){
NSInteger index=[self.firstForTable indexOfObjectIdenticalTo:dInner];
isAlreadyInserted=(index>0 && index!=NSIntegerMax);
if(isAlreadyInserted) break;
}
if(isAlreadyInserted) {
[self miniMizeFirstsRows:ar];
} else {
NSUInteger count=indexPath.row+1;
NSMutableArray *arCells=[NSMutableArray array];
for(NSDictionary *dInner in ar ) {
[arCells addObject:[NSIndexPath indexPathForRow:count inSection:0]];
[self.firstForTable insertObject:dInner atIndex:count++];
}
[tableView1 beginUpdates];
[tableView1 insertRowsAtIndexPaths:arCells withRowAnimation:UITableViewRowAnimationNone];
[tableView1 endUpdates];
[tableView1 scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
}else{
NSLog(#"child %# %#|",[item valueForKey:#"nome"],[item valueForKey:#"produtos"]);
}
}
Current code for minimizing the cell:
-(void)miniMizeFirstsRows:(NSArray*)ar{
NSLog(#"miniMizeFirstsRows");
for(NSDictionary *dInner in ar ) {
NSUInteger indexToRemove=[self.firstForTable indexOfObjectIdenticalTo:dInner];
NSArray *arInner=[dInner valueForKey:#"produtos"];
if(arInner && [arInner count]>0){
[self miniMizeFirstsRows:arInner];
}
if([self.firstForTable indexOfObjectIdenticalTo:dInner]!=NSNotFound) {
[self.firstForTable removeObjectIdenticalTo:dInner];
[tableView beginUpdates];
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:
[NSIndexPath indexPathForRow:indexToRemove inSection:0]
]
withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
}
}
}
Thanks in Advance.
EDIT still Can't make it work
What I have, by using the help from Marco answer:
NSLog(#"indexPath1 = %i",selectedRow);
NSDictionary *d=[self.firstForTable objectAtIndex:indexPath.row];
if([d valueForKey:#"Objects"]) {
NSArray *ar=[d valueForKey:#"Objects"];
NSUInteger count=indexPath.row +1;
NSMutableArray *arCells=[NSMutableArray array];
for(NSDictionary *dInner in ar ) {
[arCells addObject:[NSIndexPath indexPathForRow:count inSection:0]];
[self.firstForTable insertObject:dInner atIndex:count++];
}
[tableView insertRowsAtIndexPaths:arCells withRowAnimation:UITableViewRowAnimationLeft];
// }
}else
{
NSLog(#"Leave Element:::%# %#|",[d valueForKey:#"name"],[d valueForKey:#"book"]);
}
// The user is selecting the cell which is currently expanded
// we want to minimize it back
if (selectedRow == row)
{
NSLog(#"selectedRow2 = %i",selectedRow);
NSDictionary *d=[self.firstForTable objectAtIndex:selectedRow];
if([d valueForKey:#"Objects"]) {
NSArray *ar=[d valueForKey:#"Objects"];
[self miniMizeFirstsRows:ar];
}
selectedRow = -1;
return;
}
// First we check if a cell is already expanded.
// If it is we want to minimize make sure it is reloaded to minimize it back
if (selectedRow >= 0)
{
NSLog(#"selectedRow3 = %i",selectedRow);
NSDictionary *d=[self.firstForTable objectAtIndex:selectedRow];
if([d valueForKey:#"Objects"]) {
NSArray *ar=[d valueForKey:#"Objects"];
[self miniMizeFirstsRows:ar];
}
selectedRow = row;
}
// Finally set the selected index to the new selection and reload it to expan
selectedRow = row;
[tableView beginUpdates]; [tableView endUpdates];
}
Some more help please :)
One thing missing from Marco's answer is the implementation of "heightForRowAtIndexPath" Delegate method.
So these are the steps you need to follow:
Create a variable to record the selected row number
Update that variable when a row is selected (in "didSelectRowAtIndexPath" delegate method) and call tableView's beginUpdates & endUpdates methods.
Return bigger height when indexPath.row == selectedRow, else return normal height.
You need an instance variable to track your selected cell.
NOTE: The code below is not meant to replace your tableview data source and delegate methods, but as an example to track a selected cell:
Add an NSInteger selectedRow instance variable to your view controller.
In viewDidLoad, initialize selectedRow to indicate no cell will be expanded:
- (void)viewDidLoad
{
[super viewDidLoad];
// Set set our selectedRow to -1 to indicate no cell will be expanded
selectedRow = -1;
}
In tableView:didSelectRowAtIndexPath::
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSInteger row = indexPath.row;
// The user is selecting the cell which is currently expanded
// we want to minimize it back
if (selectedRow == row)
{
selectedRow = -1;
[tableView beginUpdates]; [tableView endUpdates];
return;
}
// First we check if a cell is already expanded.
// If it is we want to minimize make sure it is reloaded to minimize it back
if (selectedRow >= 0)
{
selectedRow = row;
}
// Finally set the selected index to the new selection and reload it to expand
selectedRow = row;
[tableView beginUpdates]; [tableView endUpdates];
}

Expand/collapse cell collapse row when other rows selected in ios

I am expanding and collapsing table view using plist value from one git hub tutorial. In that tutorial when i press row it is expanding, when i press the same row it is again collapsing no problem in that. But what i want is when i press a row expect that row other opened rows should be collapsed, so could any one give me some idea.
This is the code for expanding and collapsing
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSDictionary *d=[self.arForTable objectAtIndex:indexPath.row];
NSLog(#"%#",d);
if([d valueForKey:#"Objects"]) {
NSArray *ar=[d valueForKey:#"Objects"];
NSLog(#"%#",ar);
BOOL isAlreadyInserted=NO;
for(NSDictionary *dInner in ar ){
NSInteger index=[self.arForTable indexOfObjectIdenticalTo:dInner];
NSLog(#"%ld",(long)index);
isAlreadyInserted=(index>0 && index!=NSIntegerMax);
if(isAlreadyInserted) break;
}
if(isAlreadyInserted)
{
[self miniMizeThisRows:ar];
}
else
{
NSUInteger count=indexPath.row+1;
NSMutableArray *arCells=[NSMutableArray array];
for(NSDictionary *dInner in ar ) {
[arCells addObject:[NSIndexPath indexPathForRow:count inSection:0]];
[self.arForTable insertObject:dInner atIndex:count++];
}
[tableView insertRowsAtIndexPaths:arCells withRowAnimation:UITableViewRowAnimationLeft];
}
}
}
-(void)miniMizeThisRows:(NSArray*)ar{
for(NSDictionary *dInner in ar ) {
NSUInteger indexToRemove=[self.arForTable indexOfObjectIdenticalTo:dInner];
NSArray *arInner=[dInner valueForKey:#"Objects"];
if(arInner && [arInner count]>0){
[self miniMizeThisRows:arInner];
}
if([self.arForTable indexOfObjectIdenticalTo:dInner]!=NSNotFound)
{
[self.arForTable removeObjectIdenticalTo:dInner];
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:
[NSIndexPath indexPathForRow:indexToRemove inSection:1]
]
withRowAnimation:UITableViewRowAnimationRight];
}
}
}
That means you want to expand exactly one cell at a time. So you should save the index path of last expanded row and you should call your method for that index path and at the same time you should insert cell for row which you are expecting to expand.
UPDATED
Make member variable in .h
NSIndexPath *lastIndexPath;
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
if(lastIndexPath.row == indexPath.row)
{
NSDictionary *d=[self.arForTable objectAtIndex:indexPath.row];
if([d valueForKey:#"Objects"]) {
NSArray *ar=[d valueForKey:#"Objects"];
}
[self miniMizeThisRows:ar];
}
else
{
if(lastIndexPath.row)
{
NSDictionary *d=[self.arForTable objectAtIndex:lastIndexPath.row];
if([d valueForKey:#"Objects"]) {
NSArray *ar=[d valueForKey:#"Objects"];
[self miniMizeThisRows:ar];
}
}
NSUInteger count=indexPath.row+1;
NSMutableArray *arCells=[NSMutableArray array];
for(NSDictionary *dInner in ar ) {
[arCells addObject:[NSIndexPath indexPathForRow:count inSection:0]];
[self.arForTable insertObject:dInner atIndex:count++];
lastIndexPath = indexPath;
[tableView insertRowsAtIndexPaths:arCells withRowAnimation:UITableViewRowAnimationLeft];
}
}
}
Please excuse if any bracket is missed. Please notify me regarding that.

Resources