扩展和折叠tableView部分iOS?

我能够成功地展开和折叠tableView部分但是到目前为止我无法为各个部分执行此操作。所有部分同时折叠或展开,这是因为我调用[tableView reloadData] .So怎么能我扩展或折叠特定部分?

这是我目前正在做的事情。

  -(UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { headerLabel = [[UILabel alloc]init]; headerLabel.tag = section; headerLabel.userInteractionEnabled = YES; headerLabel.backgroundColor = [[UIColor grayColor]colorWithAlphaComponent:0.2]; headerLabel.text = [menuCategoryArray objectAtIndex:section]; headerLabel.frame = CGRectMake(5, 0, tableView.tableHeaderView.frame.size.width, tableView.tableHeaderView.frame.size.height); UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(headerClicked:)]; tapGesture.cancelsTouchesInView = NO; [headerLabel addGestureRecognizer:tapGesture]; return headerLabel; } -(void)headerClicked:(UIGestureRecognizer*)sender { if (!isShowingList) { isShowingList=YES; [self.menuTableView reloadData]; UILabel *lbl = (UILabel*)sender.view; NSLog(@"header no : %d", lbl.tag); }else{ isShowingList=NO; [self.menuTableView reloadData]; UILabel *lbl = (UILabel*)sender.view; NSLog(@"header no : %d", lbl.tag); } } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ if (isShowingList) { return [[[[jsonArray valueForKey:@"menus"] valueForKey:@"menuName"] objectAtIndex:section] count]; }else{ return 0; } return 0; } 

首先将isShowingList作为

 @property (nonatomic, strong) NSMutableArray *isShowingList; 

要识别以前打开的部分,您需要另一个属性

 @property (nonatomic, assign) NSInteger openSectionIndex; 

当你初始化数据时,在你的情况下是isShowingList在重新加载表之前初始化isShowingList数组

 self.isShowingList = [NSMutableArray array]; if (jsonArray && [jsonArray valueForKey:@"menus"] && [[jsonArray valueForKey:@"menus"] valueForKey:@"menuName"]) { for (int i = 0; i < [[[jsonArray valueForKey:@"menus"] valueForKey:@"menuName"] count]; i++) { [self.isShowingList addObject:[NSNumber numberWithBool:NO]]; } } 

并在viewDidLoad()初始化openSectionIndex

 self.openSectionIndex = NSNotFound; 

你的代码应该像这样改变

 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { if ([[self.isShowingList objectAtIndex:section] boolValue]) { return [[[[jsonArray valueForKey:@"menus"] valueForKey:@"menuName"] objectAtIndex:section] count]; } else { return 0; } return 0; } -(void)headerClicked:(UIGestureRecognizer*)sender { UILabel *lbl = (UILabel*)sender.view; NSLog(@"header no : %d", lbl.tag); if ([[self.isShowingList objectAtIndex:lbl.tag] boolValue]) { [self closeSection:lbl.tag]; } else { [self openSection:lbl.tag]; } } //methods for expanding and collapsing sections - (void)openSection:(NSInteger)section { [self.isShowingList replaceObjectAtIndex:section withObject:[NSNumber numberWithBool:YES]]; NSInteger countOfRowsToInsert = [[[[jsonArray valueForKey:@"menus"] valueForKey:@"menuName"] objectAtIndex:section] count]; NSMutableArray *indexPathsToInsert = [[NSMutableArray alloc] init]; for (NSInteger i = 0; i < countOfRowsToInsert; i++) { [indexPathsToInsert addObject:[NSIndexPath indexPathForRow:i inSection:section]]; } NSMutableArray *indexPathsToDelete = [[NSMutableArray alloc] init]; NSInteger previousOpenSectionIndex = self.openSectionIndex; if (previousOpenSectionIndex != NSNotFound) { dispatch_async(dispatch_get_main_queue(), ^{ [self.menuTableView reloadSections:[NSIndexSet indexSetWithIndex:previousOpenSectionIndex] withRowAnimation:UITableViewRowAnimationNone]; }); [self.isShowingList replaceObjectAtIndex:previousOpenSectionIndex withObject:[NSNumber numberWithBool:NO]]; NSInteger countOfRowsToDelete = [[[[jsonArray valueForKey:@"menus"] valueForKey:@"menuName"] objectAtIndex:previousOpenSectionIndex] count]; for (NSInteger i = 0; i < countOfRowsToDelete; i++) { [indexPathsToDelete addObject:[NSIndexPath indexPathForRow:i inSection:previousOpenSectionIndex]]; } } // Apply the updates. [self.menuTableView beginUpdates]; [self.menuTableView insertRowsAtIndexPaths:indexPathsToInsert withRowAnimation:UITableViewRowAnimationAutomatic]; [self.menuTableView deleteRowsAtIndexPaths:indexPathsToDelete withRowAnimation:UITableViewRowAnimationAutomatic]; [self.menuTableView endUpdates]; self.openSectionIndex = section; } - (void)closeSection:(NSInteger)section { [self.isShowingList replaceObjectAtIndex:section withObject:[NSNumber numberWithBool:NO]]; NSInteger countOfRowsToDelete = [self.menuTableView numberOfRowsInSection:section]; if (countOfRowsToDelete > 0) { NSMutableArray *indexPathsToDelete = [[NSMutableArray alloc] init]; for (NSInteger i = 0; i < countOfRowsToInsert; i++) { [indexPathsToDelete addObject:[NSIndexPath indexPathForRow:i inSection:section]]; } [self.menuTableView deleteRowsAtIndexPaths:indexPathsToDelete withRowAnimation:UITableViewRowAnimationTop]; } self.openSectionIndex = NSNotFound; } 

你真的会更好地使用’tableView更新块’。 请看一下这个viewController,我最近发布了一个答案。 updateBlock允许您操作影响dataSource的某个变量或其他变量,并指示表添加/删除行/部分以反映该更改。 请注意,当您调用endUpdates方法时,表不得与模型冲突,否则您将获得exception。

 #import "ViewController.h" //dont worry, the header is empty except for import , this is a subclass on UIViewController @interface ViewController () @property (weak, nonatomic) UITableView *tableView; @end @implementation ViewController { //ivars BOOL sectionIsOpen[4]; //we will use this BOOL array to keep track of the open/closed state for each section. Obviously I have the number of sections fixed at 4 here, but you could make a more dynamic array with malloc() if neccesary.. } - (void)viewDidLoad { [super viewDidLoad]; UITableView *tv = [[UITableView alloc]initWithFrame:self.view.bounds style:UITableViewStyleGrouped]; tv.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; tv.dataSource = self; tv.delegate = self; [self.view addSubview:tv]; self.tableView = tv; // Do any additional setup after loading the view, typically from a nib. } #pragma mark - UITableViewDataSource -(NSInteger )numberOfSectionsInTableView:(UITableView *)tableView{ return 4; } -(NSInteger )tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ return ((sectionIsOpen[section]) ? [self numberOfRowsInSection:section] : 0); } -(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{ //put your switch() here... return [NSString stringWithFormat:@"I am section %i", (int)section ]; } -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ static NSString *cellId = @"cellID"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId]; if (!cell) { cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellId]; } //etc etc decorate your cell... cell.textLabel.text = [NSString stringWithFormat:@"cell %i / %i", (int)indexPath.section, (int)indexPath.row ]; return cell; } #pragma mark - UITableViewDelegate -(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ const CGRect fr = CGRectMake(0, 0, 320.0, 40.0 ); UIButton *btn = [[UIButton alloc]initWithFrame:fr]; [btn setTitle:[self tableView:tableView titleForHeaderInSection:section] forState:UIControlStateNormal ]; [btn setTag:section]; [btn addTarget:self action:@selector(sectionOpenToggle:) forControlEvents:UIControlEventTouchUpInside]; // add an image, colour etc if you like return btn; } #pragma mark - tableViewHelpers //the number of rows in sectionX when it is open... -(NSInteger )numberOfRowsInSection:(NSInteger )section{ //get your count from your model return section + 1; } //opening/closing a section -(void )setSection:(NSInteger )section toOpen:(BOOL )open{ if (open != sectionIsOpen[section]) { //build an array of indexPath objects NSMutableArray *indxPths = [NSMutableArray array]; for (NSInteger row = 0; row < [self numberOfRowsInSection:section]; row ++) { [indxPths addObject: [NSIndexPath indexPathForRow:row inSection:section ] ]; } [self.tableView beginUpdates]; if (open) { [self.tableView insertRowsAtIndexPaths:indxPths withRowAnimation:UITableViewRowAnimationFade]; //nb there is a large ENUM of tableViewRowAnimation types to experiment with.. }else{ [self.tableView deleteRowsAtIndexPaths:indxPths withRowAnimation:UITableViewRowAnimationFade]; } sectionIsOpen[section] = open; [self.tableView endUpdates]; } } -(void )sectionOpenToggle:(id )sender{ [self setSection:[sender tag] toOpen: !sectionIsOpen[[sender tag]] ]; } // open/close all sections. -(void )setAllSectionsOpen:(BOOL )open{ for (NSInteger section = 0; section < [self numberOfSectionsInTableView:self.tableView]; section ++) { [self setSection:section toOpen:open]; } } //these two for your convenience, hook up to navbar items etc.. -(IBAction)openAllSections:(id)sender{ [self setAllSectionsOpen:YES]; } -(IBAction)closeAllSections:(id)sender{ [self setAllSectionsOpen:NO]; } @end