【iOS】UITableView中section的展开和收起
来源:互联网 发布:人工智能行业研究报告 编辑:程序博客网 时间:2024/05/16 04:25
我们在做项目时,经常遇到UITableView需要展开与收起的情况,类似手机QQ的折叠,而且根据数据的不同判断有多少行需要展开与收起.之前做项目的时候也使用过,最近有时间整理,就把之前是怎么操作的记录下来。
首先,我们先说下思路:
思路:在写代码的时候我们可以很容易的写出cell和setion。但是系统并没有提供记录section状态的方法或是属性。我们需要点击某个section的时候收起和弹出cell。怎么做呢?只有是人为的给section增加一个标记了,每个section一个标记,section被点击了就把这个状态标记取反,根据这个标记来展开和收起cell
其中,设置方式又分为两种:
第一种:
设置cell的高度,高度为0了cell就收起了,高度大于0了cell就弹出
下面就直接贴代码了。
ViewController.m
#import "ViewController.h"#import "SectionViewController.h"@interface ViewController ()<UITableViewDataSource,UITableViewDelegate>@property (nonatomic,strong)UITableView *tableView;@property (nonatomic,strong)NSMutableArray *sectionArray;@property (nonatomic,strong)NSMutableArray *flagArray;@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; [self makeData]; _tableView = [[UITableView alloc] initWithFrame:self.view.frame style:UITableViewStyleGrouped]; _tableView.delegate = self; _tableView.dataSource = self; [self.view addSubview:_tableView]; // Do any additional setup after loading the view, typically from a nib.}- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}/** * 处理数据 _sectionArray里面存储数组 */- (void)makeData{ _sectionArray = [NSMutableArray array]; _flagArray = [NSMutableArray array]; NSInteger num = 6; for (int i = 0; i < num; i ++) { NSMutableArray *rowArray = [NSMutableArray array]; for (int j = 0; j < arc4random()%20 + 1; j ++) { [rowArray addObject:[NSString stringWithFormat:@"%d",j]]; } [_sectionArray addObject:rowArray]; [_flagArray addObject:@"0"]; }}//设置组数- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ return _sectionArray.count;}//设置行数- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ NSArray *arr = _sectionArray[section]; return arr.count;}//组头高度-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ return 44;}//cell的高度- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ if ([_flagArray[indexPath.section] isEqualToString:@"0"]) return 0; else return 44;}//组头- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ UILabel *sectionLabel = [[UILabel alloc] init]; sectionLabel.frame = CGRectMake(0, 0, self.view.frame.size.width, 444); sectionLabel.textColor = [UIColor orangeColor]; sectionLabel.text = [NSString stringWithFormat:@"组%d",section]; sectionLabel.textAlignment = NSTextAlignmentCenter; sectionLabel.tag = 100 + section; sectionLabel.userInteractionEnabled = YES; sectionLabel.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"itembg.png"]]; UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(sectionClick:)]; [sectionLabel addGestureRecognizer:tap]; return sectionLabel;}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ static NSString *identify = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identify]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identify]; } cell.textLabel.text= [NSString stringWithFormat:@"第%d组的第%d个cell",indexPath.section,indexPath.row]; cell.clipsToBounds = YES;//这句话很重要,防止cell覆盖显示 return cell;}- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ SectionViewController *sVC = [[SectionViewController alloc] init]; sVC.rowLabelText = [NSString stringWithFormat:@"第%d组的第%d个cell",indexPath.section,indexPath.row]; [self presentViewController:sVC animated:YES completion:nil];}- (void)sectionClick:(UITapGestureRecognizer *)tap{ int index = tap.view.tag % 100; NSMutableArray *indexArray = [[NSMutableArray alloc]init]; NSArray *arr = _sectionArray[index]; for (int i = 0; i < arr.count; i ++) { NSIndexPath *path = [NSIndexPath indexPathForRow:i inSection:index]; [indexArray addObject:path]; } //展开 if ([_flagArray[index] isEqualToString:@"0"]) { _flagArray[index] = @"1"; [_tableView reloadRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationBottom]; //使用下面注释的方法就 注释掉这一句 } else { //收起 _flagArray[index] = @"0"; [_tableView reloadRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationTop]; //使用下面注释的方法就 注释掉这一句 } //另一种刷新方式 // NSRange range = NSMakeRange(index, 1); // NSIndexSet *sectionToReload = [NSIndexSet indexSetWithIndexesInRange:range]; // [_tableView reloadSections:sectionToReload withRowAnimation:UITableViewRowAnimationAutomatic];}@end
附上代码的下载地址:Demo地址
第二种:
设置section数组的个数,数组个数为0了cell就收起了,数组个数大于0了cell就弹出
demo:
附上主要代码片段,仅提供思路参考:
1.设置数据源:
//设置属性@property(nonatomic, strong) NSMutableArray* listArray;/**< 数组 */@property(nonatomic, strong) NSMutableDictionary* foldInfoDic;/**< 存储开关字典 */@property(nonatomic, strong) NSDictionary *topDic;@property(nonatomic, strong) NSDictionary *orderDic;@property(nonatomic, strong) NSDictionary *userDic;@property(nonatomic, strong) NSDictionary *accountDic;@property(nonatomic, strong) NSDictionary *paymentDic;@property(nonatomic, strong) NSDictionary *bootomDic;#pragma marl ---load lazing-(NSDictionary *)topDic{ if (!_topDic) { _topDic = @{@"title":@"",@"data":@[@""]}; } return _topDic; }-(NSDictionary *)orderDic{ if (!_orderDic) { _orderDic = @{@"title":@"订单信息",@"data":@[@"订单信息",@"收益",@"交易类型",@"支付币种",@"汇率",@"备注"]}; } return _orderDic; }-(NSDictionary *)userDic{ if (!_userDic) { _userDic = @{@"title":@"用户信息",@"data":@[@"用户名",@"联系方式"]}; } return _userDic;}-(NSDictionary *)accountDic{ if (!_accountDic) { _accountDic = @{@"title":@"收款账户信息",@"data":@[@"联系方式",@"开户银行",@"开户名"]}; } return _accountDic;}-(NSDictionary *)paymentDic{ if (!_paymentDic) { _paymentDic = @{@"title":@"汇款凭证",@"data":@[@""]}; } return _paymentDic;}-(NSDictionary *)bootomDic{ if (!_bootomDic) { _bootomDic = @{@"title":@"",@"data":@[@"订单编号",@"下单时间"]}; } return _bootomDic; }-(NSMutableArray *)listArray{ if (!_listArray) { _listArray = [NSMutableArray array]; } return _listArray; }-(NSMutableDictionary *)foldInfoDic{ if (!_foldInfoDic) { _foldInfoDic = [NSMutableDictionary dictionary]; } return _foldInfoDic; }
2.根据需要加载需要的数据源,并设置记录是否展开的section对应de字典
[self.listArray addObject:self.topDic]; [self.listArray addObject:self.orderDic]; [self.listArray addObject:self.userDic]; [self.listArray addObject:self.accountDic]; //根据项目需要判断需要添加哪些section数据 if (self.orderType == FinancierAcceptarbitrateType || self.orderType == FinancierAcceptFinishType) { [self.listArray addObject:self.paymentDic]; }else{ if (self.orderType == FinancierAcceptTradingType) { } } [self.listArray addObject:self.bootomDic]; //设置section属性 for (int i=0; i<self.listArray.count; i++) { NSDictionary *dic = self.listArray[i]; NSString *key = [NSString stringWithFormat:@"%d",i]; [self.foldInfoDic setObject:@"1" forKey:key]; }
设置tableView:
#pragma mark --- UITableViewDataSource and UITableViewDelegate Methods-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ return self.listArray.count;}-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ NSDictionary *dic = self.listArray[section]; NSArray *cellArray = [NSArray arrayWithArray:dic[@"data"]]; NSString *key = [NSString stringWithFormat:@"%d",(int)section]; BOOL folded = [[self.foldInfoDic objectForKey:key] boolValue]; if (folded) { return cellArray.count; }else{ return 0; }}-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ if (indexPath.section == 0 ) { static NSString *CellIdentifier = @"FinancierAcceptDetailTopCell"; FinancierAcceptDetailTopCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[FinancierAcceptDetailTopCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; cell.selectionStyle = UITableViewCellSelectionStyleNone; } cell.orderType = self.orderType; // cell.delegate = self; cell.layer.masksToBounds = YES; return cell; }else{ static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier]; cell.selectionStyle = UITableViewCellSelectionStyleNone; cell.textLabel.textColor = [UIColor grayColor]; cell.textLabel.font = [UIFont systemFontOfSize:15]; cell.detailTextLabel.textColor = [UIColor blackColor]; cell.detailTextLabel.font = [UIFont systemFontOfSize:15]; } //清界面-- for (UIView *view in cell.subviews) { if ([view isKindOfClass:[UIImageView class]]) { [view removeFromSuperview]; } if ([view isKindOfClass:[UILabel class]]) { [view removeFromSuperview]; } } NSDictionary *dic = self.listArray[indexPath.section]; NSArray *cellArray = [NSArray arrayWithArray:dic[@"data"]]; NSString *title = [NSString stringWithFormat:@"%@",dic[@"title"]]; if ([title isEqualToString:@"汇款凭证"]) { cell.textLabel.text = @""; cell.detailTextLabel.text = @""; _paymentImg = [[UIImageView alloc] initWithFrame:CGRectMake((mainWidth-255)/2, 15, 255, 160)]; [cell addSubview:_paymentImg]; //判断下imgView _paymentImg.image = [UIImage imageNamed:@"A5_2_payment"]; }else{ cell.textLabel.text = cellArray[indexPath.row]; cell.detailTextLabel.text = [NSString stringWithFormat:@"test%ld-%ld",indexPath.section,indexPath.row]; } cell.layer.masksToBounds = YES; return cell; }}-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ if (indexPath.section == 0) { if (self.orderType ==FinancierAcceptTradingType ||self.orderType ==FinancierAcceptCancelType) { return 140; } return 104; } NSDictionary *dic = self.listArray[indexPath.section]; NSString *title = [NSString stringWithFormat:@"%@",dic[@"title"]]; if ([title isEqualToString:@"汇款凭证"]) { return 190; } return 44;}-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ [tableView deselectRowAtIndexPath:indexPath animated:YES]; }- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ if (section == 0) { return 0.01; }else if (section == self.listArray.count-1) { return 0.01; } return 44; }- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{ return 10;}-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ if (section == 0 || (section == self.listArray.count-1)) { UIView *view = [[UIView alloc] init]; return view; }else{ FinancierHeaderView *headerView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:@"header"]; if (!headerView) { headerView = [[FinancierHeaderView alloc] initWithReuseIdentifier:@"header"]; } NSDictionary *dic = self.listArray[section]; NSString *title = [NSString stringWithFormat:@"%@",dic[@"title"]]; [headerView setFoldSectionHeaderViewWithTitle:title section:section canFold:YES]; headerView.delegate = self; NSString *key = [NSString stringWithFormat:@"%d", (int)section]; BOOL folded = [[_foldInfoDic objectForKey:key] boolValue]; headerView.fold = folded; return headerView; } }- (void)foldHeaderInSection:(NSInteger)SectionHeader { NSString *key = [NSString stringWithFormat:@"%d",(int)SectionHeader]; BOOL folded = [[_foldInfoDic objectForKey:key] boolValue]; NSString *fold = folded ? @"0" : @"1"; [self.foldInfoDic setObject:fold forKey:key]; // NSMutableIndexSet *set = [[NSMutableIndexSet alloc] initWithIndex:SectionHeader]; // [_tableView reloadSections:set withRowAnimation:UITableViewRowAnimationNone]; //刷整个section NSIndexSet *indexSet=[[NSIndexSet alloc]initWithIndex:SectionHeader]; [self.tableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationAutomatic]; //展开 // if (folded) { // [_tableView reloadSections:set withRowAnimation:UITableViewRowAnimationBottom]; // // } else { //收起 // [_tableView reloadSections:set withRowAnimation:UITableViewRowAnimationTop]; // }}其中,FinancierHeaderView自定义的tableHeaderView
FinancierHeaderView.h
#import <UIKit/UIKit.h>@protocol FinancierHeaderViewCellDelegate <NSObject>- (void)foldHeaderInSection:(NSInteger)SectionHeader;@end@interface FinancierHeaderView : UITableViewHeaderFooterView@property(nonatomic,strong) UIImageView *rightImg;@property(nonatomic,strong) UIView *headerView;@property(nonatomic,strong) UIButton* rightBtn;@property(nonatomic,strong) UILabel*titleLb;@property(nonatomic,assign) NSInteger index;@property(nonatomic,weak)id<FinancierHeaderViewCellDelegate> delegate;@property(nonatomic, assign) BOOL fold;/**< 是否折叠 */@property(nonatomic, assign) NSInteger section;/**< 选中的section */- (void)setFoldSectionHeaderViewWithTitle:(NSString *)title section:(NSInteger)section canFold:(BOOL)canFold;@end
FinancierHeaderView.m
#import "FinancierHeaderView.h"@interface FinancierHeaderView(){ BOOL _created;/**< 是否创建过 */ BOOL _canFold;/**< 是否可展开 */ }@end@implementation FinancierHeaderView- (instancetype)initWithReuseIdentifier:(NSString *)reuseIdentifier{ self = [super initWithReuseIdentifier:reuseIdentifier]; if (self) { // [self setUpUI];//_init表示初始化方法 } return self;}- (void)setFoldSectionHeaderViewWithTitle:(NSString *)title section:(NSInteger)section canFold:(BOOL)canFold{ if (!_created) { [self setUpUI]; } _titleLb.text = title; _section = section; _canFold = canFold; if (canFold) { _rightImg.hidden = NO; } else { _rightImg.hidden = YES; }}- (void)setUpUI{ _created = YES; CGFloat space = 10; _headerView = [[UIView alloc] init]; _headerView.backgroundColor = [UIColor whiteColor]; [self addSubview:_headerView]; [_headerView mas_makeConstraints:^(MASConstraintMaker *make) { make.top.mas_equalTo(0); make.left.mas_equalTo(0); make.width.mas_equalTo(mainWidth); make.height.mas_equalTo(44); }]; _titleLb = [[UILabel alloc] init]; _titleLb.font = [UIFont systemFontOfSize:15]; [_headerView addSubview:_titleLb]; [_titleLb mas_makeConstraints:^(MASConstraintMaker *make) { make.top.mas_equalTo(0); make.left.mas_equalTo(space); make.width.mas_equalTo(mainWidth-50); make.height.mas_equalTo(44); }]; _rightImg = [[UIImageView alloc] initWithFrame:CGRectMake(mainWidth-40, 17, 20, 10)]; _rightImg.image = [UIImage imageNamed:@"A5_up"]; [_headerView addSubview:_rightImg]; [_rightImg mas_makeConstraints:^(MASConstraintMaker *make) { make.top.mas_equalTo(17); make.left.mas_equalTo(mainWidth-40); make.width.mas_equalTo(20); make.height.mas_equalTo(10); }]; _rightBtn = [UIButton buttonWithType:UIButtonTypeCustom]; _rightBtn.selected = YES; [_rightBtn addTarget:self action:@selector(rightBtnClick:) forControlEvents:UIControlEventTouchUpInside ]; [_headerView addSubview:_rightBtn]; [_rightBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.top.mas_equalTo(0); make.left.mas_equalTo(0); make.width.mas_equalTo(mainWidth); make.height.mas_equalTo(44); }]; UIView *lineView = [[UIView alloc] init]; lineView.backgroundColor = [UIColor groupTableViewBackgroundColor]; [_headerView addSubview:lineView]; [lineView mas_makeConstraints:^(MASConstraintMaker *make) { make.top.mas_equalTo(43.6); make.left.mas_equalTo(0); make.width.mas_equalTo(mainWidth); make.height.mas_equalTo(0.4); }];}- (void)rightBtnClick:(UIButton *)sender{ if (_canFold) { if ([self.delegate respondsToSelector:@selector(foldHeaderInSection:)]) { [self.delegate foldHeaderInSection:_section]; } }}- (void)setFold:(BOOL)fold { _fold = fold; if (fold) { _rightImg.image = [UIImage imageNamed:@"A5_up"]; } else { _rightImg.image = [UIImage imageNamed:@"A5_down"]; }}@end
OK,以后有空在整理下第二种方式的代码
阅读全文
0 0
- 【iOS】UITableView中section的展开和收起
- 【iOS】UITableView中section的展开和收起
- UITableView 的展开和 收起
- cell的展开和收起
- iOS cell的展开与收起
- 自定义UITableView,实现cell的三级分组展开收起
- UITableView cell的展开与收起(伴随指示箭头)
- 使用listview的展开和收起效果
- 可展开和收起的LinearLayout
- 可展开和收起的LinearLayout
- 可展开和收起的LinearLayout
- 可展开和收起的LinearLayout
- js实现菜单的收起和展开
- webView 收起和展开
- TextView展开和收起
- 获取UItableView中button所在的section和row
- iOS通用库----TableView多项选择全选和展开收起
- iOS中添加UITapGestureRecognizer手势识别后,UITableView的didSelectRowAtIndexPath失效 或者点击UITableView的空白处收起键盘
- 2017面试题的总结——附加答案
- Apache与Tomcat有什么关系和区别
- 添加表单
- NoClassDefFoundError异常处理办法
- 有关url的php内置函数
- 【iOS】UITableView中section的展开和收起
- 【C++多态】与虚函数简单总结
- input文本框中value值有双引号的问题
- 命名空间
- test
- Android实现动画效果
- JACO2 6自由度机械臂上手体验二
- commons.lang
- 如何在ubuntu 14.04系统下开启nfs网络文件系统