问题描述:

I want to make this type of expandable/collapsible table view.

there are categories and subcategories as in picture.

for example "health and beauty" is a category and when i click this cell than its open subcategories as in picture below.

So how can I make this type of table view?

please suggest me.

网友答案:

Finally i get two very useful helping link below which describes exact what the requirement is here Expanding/Collapsing TableView Sections
Collapsable Table View for iOS

Really, good articles for such kind of expanding/collapsing tableview sections

网友答案:

Use Following code for expandable Cell into UITableView

- (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;
}

code for expanding & collapsing rows – TableView DidSelectRow Method

- (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];
        }
    }
}

A Method which will help to minimize & maximize/expand-collapse 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.tableView deleteRowsAtIndexPaths:
              [NSArray arrayWithObject:[NSIndexPath indexPathForRow:indexToRemove inSection:0]]
                      withRowAnimation:UITableViewRowAnimationRight];
        }
    }
}

You can download source code from here.

网友答案:

If this helps: [Access uitableview's expandable and collapsable sections] https://github.com/OliverLetterer/UIExpandableTableView

网友答案:

Try Using this code... May be this can help.. And Feel free to Edit the code according to your requirements...

#import "ViewController.h"
#import <QuartzCore/QuartzCore.h>
@interface ViewController ()

@end

@implementation ViewController
@synthesize myTable;
- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    //myTable.backgroundColor=[UIColor clearColor];
   // self.view.backgroundColor=[UIColor colorWithPatternImage:[UIImage imageNamed:@"wood.png"]];
    muArr= [[NSMutableArray alloc]initWithObjects:@"Vinay",@"Anmol",@"Jagriti", nil];
    ExpArr=[[NSMutableArray alloc]initWithObjects:@"Useeee",@"Thissss",@"Codeee", nil];
    otherExpand=100;
    checker=100;

}

-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{
    return muArr.count;
}

-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if(otherExpand==section)
    return ExpArr.count;

    return  0;

}

-(BOOL)tableView:(UITableView *)table canCollapse:(NSIndexPath *)indexPath
{

    return NO;
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *[email protected]"Cell";
    UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:Identifier];
    if (cell==nil)
    {
        cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:Identifier];

    }
    cell.textLabel.text=[ExpArr objectAtIndex:indexPath.row];
    cell.textLabel.backgroundColor=[UIColor clearColor];
    UIView *viewww=[[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
    viewww.backgroundColor=[UIColor colorWithPatternImage:[UIImage imageNamed:@"wood.png"]];
    cell.backgroundView=viewww;

   // cell.backgroundColor=[UIColor colorWithPatternImage:[UIImage imageNamed:@"wood.png"]];
    [tableView setSeparatorStyle:UITableViewCellSeparatorStyleSingleLineEtched];
    [tableView setSeparatorColor:[UIColor purpleColor]];

    return cell;

}

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

    UIView *view1=[[UIView alloc]initWithFrame:CGRectMake(0, 0, 320, 44)];
    [view1.layer setCornerRadius:20];
    view1.layer.borderWidth=2;
    view1.layer.borderColor=[UIColor brownColor].CGColor;
    UILabel *label=[[UILabel alloc]initWithFrame:CGRectMake(10, 0, 295, 44)];
    label.backgroundColor=[UIColor clearColor];

    label.text=[muArr objectAtIndex:section];
    UIButton *btn=[UIButton buttonWithType:UIButtonTypeDetailDisclosure];
    btn.frame=CGRectMake(280, -5, 50, 50);
    btn.backgroundColor=[UIColor clearColor];
    btn.tag=section;

    view1.backgroundColor=[UIColor colorWithPatternImage:[UIImage imageNamed:@"wood.png"]];
    label.textColor=[UIColor blackColor];
    label.font=[UIFont fontWithName:@"American TypeWriter" size:18];
    //btn.backgroundColor=[UIColor blackColor];
    [view1 addSubview:btn];
    [view1 addSubview:label];

    [btn addTarget:self action:@selector(Btntap:) forControlEvents:UIControlEventTouchUpInside];

    return view1;
}


-(void)Btntap : (UIButton *)btn
{
    if(otherExpand!=100)
    {
        if (otherExpand==btn.tag)
        {
            NSMutableArray *tempArr2=[[NSMutableArray alloc]init];
            for(int j=0;j<ExpArr.count;j++)
            {
                NSIndexPath *indexx1=[NSIndexPath indexPathForRow:j inSection:otherExpand];
                [tempArr2 addObject:indexx1];
            }
            checker=0;
            otherExpand=100;
            [myTable deleteRowsAtIndexPaths:tempArr2 withRowAnimation:UITableViewRowAnimationAutomatic];
        }

        else
        {
            NSMutableArray *tempArr2=[[NSMutableArray alloc]init];
            for(int j=0;j<ExpArr.count;j++)
            {
                NSIndexPath *indexx1=[NSIndexPath indexPathForRow:j inSection:otherExpand];
                [tempArr2 addObject:indexx1];
            }
            checker=1;
            otherExpand=100;
            [myTable deleteRowsAtIndexPaths:tempArr2 withRowAnimation:UITableViewRowAnimationAutomatic];
        }
    }

    if(checker!=0)
    {
        otherExpand=btn.tag;
        //checker=
        NSMutableArray *tempArr=[[NSMutableArray alloc]init];
        for(int i=0;i<ExpArr.count;i++)
        {
            NSIndexPath *indexx=[NSIndexPath indexPathForRow:i inSection:btn.tag];
            [tempArr addObject:indexx];
        }
        [myTable insertRowsAtIndexPaths:tempArr withRowAnimation:UITableViewRowAnimationAutomatic];

        checker=1;
    }
    checker=100;
}



-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    return 44;
}

@end
网友答案:

I have a little bit of a different approach to expandable table views - one that aligns with how these kinds of table views are generally built.

There are headers and there are cells. Headers should be tappable, and then cells underneath the headers would show or hide. This can be achieved by adding a gesture recognizer to the header, and when tapped, you just remove all of the cells underneath that header (the section), and viceversa (add cells). Of course, you have to maintain state of which headers are "open" and which headers are "closed."

This is nice for a couple of reasons:

  1. The job of headers and cells are separated which makes code cleaner.
  2. This method flows nicely with how table views are built (headers and cells) and, therefore, there isn't much magic - the code is simply removing or adding cells, and should be compatible with later versions of iOS.

I made a very simple library to achieve this. As long as your table view is set up with UITableView section headers and cells, all you have to do is subclass the tableview and the header. Try it :)

Link: https://github.com/fuzz-productions/FZAccordionTableView

网友答案:

There is a great video in WWDC 2011 called UITableView Changes, Tips and Tricks - session 125 that shows how to do things like this.
Also check out the example code TVAnimationsGestures

网友答案:

You may take a look at this accordion example in Swift: https://github.com/tadija/AEAccordion

It's got very little code to create accordion effect (not by using sections but cells), and as a bonus there is also a solution to use XIB files inside other XIB files (useful for custom cells which use custom views).

网友答案:

Please try this example :

best example for Expandable TableView

https://github.com/OliverLetterer/UIExpandableTableView

网友答案:

TLIndexPathTools can do this sort of thing naturally. In fact, there is are extensions for both expandable sections and expandable tree structures. Try running the Collapse sample project for expandable sections and the Outline sample project for expandable trees.

One advantage of using TLIndexPathTools is that, as a simple, low-level API, it can solve all kinds of dynamic table view and collection view problems using a common approach. And it works interchangeably with Core Data and plain arrays.

网友答案:

Check this Link :

http://iostechnotips.blogspot.in/2014/05/expandable-uitableview.html

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

*Use UITableView delegate method viewForHeaderInSection and return a custom UIView.

*Add a UIButton as subview with action "expandable:(id)sender" check the sender id as section number and reload the table view.

网友答案:

In your .h file

LoadCustomCell *cell1;
NSMutableArray  *arrayForBool;
NSMutableArray  *questionArray;
NSMutableArray  *answerArray;

In your .m file

 viewDidLoadMethod {
 _faqTblView.estimatedRowHeight = 30;
 _faqTblView.rowHeight = UITableViewAutomaticDimension;
 arrayForBool = [[NSMutableArray alloc]init];

 _questionArray = [[NSMutableArray alloc]init];
 _answerArray = [[NSMutableArray alloc]init];
 for (int i = 0; i < _questionArray.count; i++) {
        [arrayForBool addObject:@"0"];
    }
    self.faqTblView.dataSource = self;
    self.faqTblView .delegate = self;
    [self.faqTblView reloadData];
 }

after that

 #pragma mark - TableView Datasource & Delegate Method.
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
  return [_questionArray count];
 }
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {

    UILabel *lblText = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 260, 100)];
    lblText.text = [_questionArray objectAtIndex:section];
    return [lblText getLabelHeight] + 20;(created custom class)
 }
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {

UITapGestureRecognizer  *headerTapped   = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(sectionHeaderTapped:)];
cell1 = [[[NSBundle mainBundle] loadNibNamed:@"LoadCustomCell" owner:self options:nil] objectAtIndex:0];
[cell1 setFrame:CGRectMake(0, 0, cell1.frame.size.width, cell1.frame.size.height)];
NSString *numStr = [NSString stringWithFormat:@"%ld. ",section + 1];
[cell1.sideMenuUserNameLabel setText:[numStr stringByAppendingString:[_questionArray objectAtIndex:section]]];
[cell1 setBackgroundColor:[UIColor lightGrayColor]];
cell1.tag = section;
[cell1 addGestureRecognizer:headerTapped];

return cell1;
}

- (void)sectionHeaderTapped:(UITapGestureRecognizer *)gestureRecognizer {

NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:gestureRecognizer.view.tag];
if (indexPath.row == 0) {
    BOOL collapsed  = [[arrayForBool objectAtIndex:indexPath.section] boolValue];
    for (int i = 0; i < [_questionArray count]; i++) {
        if (indexPath.section==i) {
            [arrayForBool removeObjectAtIndex:i];
            [arrayForBool insertObject:[NSString stringWithFormat:@"%d", !collapsed] atIndex:i];
        }
    }
    NSLog(@"%@", arrayForBool);
    [self.faqTblView reloadSections:[NSIndexSet indexSetWithIndex:gestureRecognizer.view.tag] withRowAnimation:UITableViewRowAnimationAutomatic];
    for (NSIndexPath *indexPath in self.faqTblView.indexPathsForSelectedRows) {
        [self.faqTblView deselectRowAtIndexPath:indexPath animated:NO];
         }
    cell1.imageView.transform = CGAffineTransformMakeRotation(M_PI);
     }
}

-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *questionCellIdentifier = @"questionCellIdentifier";
QuestionCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:questionCellIdentifier];
if (cell == nil) {
    NSArray * myNib;
    myNib =[[NSBundle mainBundle]loadNibNamed:@"QuestionCustomCell" owner:self options:nil];
    cell = (QuestionCustomCell *)[myNib lastObject];
}

BOOL manyCells  = [[arrayForBool objectAtIndex:indexPath.section] boolValue];
if(manyCells){
    cell.questionNameLbl.text = [_answerArray objectAtIndex:indexPath.section];
}
return cell;
}
相关阅读:
Top