这个小demo是之前项目中使用的一个需求,单独拿出来,效果还不错。主要是利用tableView自带刷新效果和scrollView的动画来实现TableView的展开与关闭功能。
主要逻辑与代码: 在tableView的代理方法
- (UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
里面做ScrollView,变化scrollView.contentOffset
来实现加减动画效果
- (UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
CGFloat headerHeight = 55;
UIView* headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, headerHeight)];
[headerView setBackgroundColor:[UIColor whiteColor]];
// 选择头View
UIView *selectView =[[UIView alloc] initWithFrame:CGRectMake(10, 15, SCREEN_WIDTH-20,40)];
selectView.layer.masksToBounds=YES;
selectView.layer.cornerRadius =3.0f;
selectView.tag =7000+section;
[headerView addSubview:selectView];
if(selectSection !=section){
selectView.layer.borderColor =RGBACOLOR(187, 187, 187, 1).CGColor;
selectView.layer.borderWidth=1.0f;
}else{
selectView.layer.borderColor =RGBACOLOR(29, 187, 214, 1).CGColor;
selectView.layer.borderWidth=1.0f;
}
// 图片背景
UIView *imageBackView =[[UIView alloc] initWithFrame:CGRectMake(0, 0, 40, 40)];
if(selectSection!=section){
imageBackView.backgroundColor =RGBACOLOR(187, 187, 187, 1);
}else{
imageBackView.backgroundColor =RGBACOLOR(29, 187, 214, 1);
}
[selectView addSubview:imageBackView];
// 动画scrollView
UIScrollView *imageScroll =[[UIScrollView alloc] initWithFrame:CGRectMake(0,0,40, 40)];
imageScroll.contentSize =CGSizeMake(40,40*2);
imageScroll.bounces =NO;
imageScroll.pagingEnabled =YES;
imageScroll.tag =section+1000;
imageScroll.backgroundColor =[UIColor clearColor];
[selectView addSubview:imageScroll];
NSArray *imageArr =@[[UIImage imageNamed:@"pluse"],[UIImage imageNamed:@"minus"]];
for (NSInteger i=0; i<2; i++) {
UIImageView *imageView =[[UIImageView alloc] initWithFrame:CGRectMake(0,i*40,40,40)];
imageView.backgroundColor =[UIColor clearColor];
imageView.image =imageArr[i];
[imageScroll addSubview:imageView];
}
if(selectSection==section){
imageScroll.contentOffset=CGPointMake(0,40);
}else{
imageScroll.contentOffset=CGPointMake(0,0);
}
UILabel* sectionLabel = [[UILabel alloc] initWithFrame:CGRectMake(55, 10, SCREEN_WIDTH - 80, 20)];
[sectionLabel setBackgroundColor:[UIColor clearColor]];
[sectionLabel setTextColor:RGBACOLOR(29, 187, 214, 1)];
[sectionLabel setFont:[UIFont systemFontOfSize:17]];
sectionLabel.text = [NSString stringWithFormat:@"Section %ld 号",(long)section];
[selectView addSubview:sectionLabel];
UITapGestureRecognizer *tapGes =[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapgesDown:)];
[selectView addGestureRecognizer:tapGes];
return headerView;
}
记录上次点击的section
比较新旧Section来刷新不同的tableViewCell
具体代码如下:
// 刷新indexpath row的标准方式
if(oldSection != selectSection){
NSMutableArray* oldIndexPathArray = [NSMutableArray arrayWithCapacity:0];
for (int i = 0; i < oldCount; i++) {
NSIndexPath* indexPath = [NSIndexPath indexPathForRow:i inSection:oldSection];
[oldIndexPathArray addObject:indexPath];
}
NSMutableArray* selectedIndexPathArray = [NSMutableArray arrayWithCapacity:0];
for (int i = 0; i < selectedCount; i++) {
NSIndexPath* indexPath = [NSIndexPath indexPathForRow:i inSection:selectSection];
[selectedIndexPathArray addObject:indexPath];
}
NSMutableArray* rowsArray = [NSMutableArray arrayWithCapacity:0];
[rowsArray addObjectsFromArray:oldIndexPathArray];
[rowsArray addObjectsFromArray:selectedIndexPathArray];
[_tableView reloadRowsAtIndexPaths:rowsArray withRowAnimation:UITableViewRowAnimationBottom];
[NSTimer scheduledTimerWithTimeInterval:0.2f target:self selector:@selector(chnageScrollView) userInfo: nil repeats:NO];
}else{
// NSLog(@">>>");
NSMutableArray* oldIndexPathArray = [NSMutableArray arrayWithCapacity:0];
for (int i = 0; i < oldCount; i++) {
NSIndexPath* indexPath = [NSIndexPath indexPathForRow:i inSection:oldSection];
[oldIndexPathArray addObject:indexPath];
}
[_tableView reloadRowsAtIndexPaths:oldIndexPathArray withRowAnimation:UITableViewRowAnimationBottom];
[NSTimer scheduledTimerWithTimeInterval:0.2f target:self selector:@selector(chnageScrollView) userInfo: nil repeats:NO];
}
特别需要注意的几个点:
1.要在代理方法- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
中控制row的行高来实现展开与关闭。不要根据行数来进行控制。
2.刷新多个section
的方法你要知道,很容易崩。
NSMutableArray* oldIndexPathArray = [NSMutableArray arrayWithCapacity:0];
for (int i = 0; i < oldCount; i++) {
NSIndexPath* indexPath = [NSIndexPath indexPathForRow:i inSection:oldSection];
[oldIndexPathArray addObject:indexPath];
}
NSMutableArray* selectedIndexPathArray = [NSMutableArray arrayWithCapacity:0];
for (int i = 0; i < selectedCount; i++) {
NSIndexPath* indexPath = [NSIndexPath indexPathForRow:i inSection:selectSection];
[selectedIndexPathArray addObject:indexPath];
}
NSMutableArray* rowsArray = [NSMutableArray arrayWithCapacity:0];
[rowsArray addObjectsFromArray:oldIndexPathArray];
[rowsArray addObjectsFromArray:selectedIndexPathArray];
[_tableView reloadRowsAtIndexPaths:rowsArray withRowAnimation:UITableViewRowAnimationBottom];
前提是方法
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
// 这个地方要全部加载进去 要不然单独刷新某Section时会崩溃 使用`heightForRowAtIndexPath`代理方法来控制展开与关闭
NSArray *array =[_origionArr objectAtIndex:section];
return array.count;
}
3.若果Section的下面有多处的cell的东西,可以添加代码cell.clipsToBounds = YES;
最后代码地址:我的Github