简单的折叠cell
文章目录
- tableView的协议执行顺序
- 折叠cell
- 基本流程
- 实战演练
tableView的协议执行顺序
在开始正式的折叠cell讲解之前,我先来讲讲tableView的协议执行顺序
对一个固定高度的tableView(即不使用我在share总结中使用的自动计算高度的内容),一个tableView的协议方法执行程序如下:
nuberOfSectionTableView
先取得这个tableView有多少个分区- 调用
numberOfRowsInSection
来获取每个节有多少个cell - 使用
cellForRowAtIndexPath
来得到每个row中的cell - 再用
heightForRowAtIndexPath
来获取每个cell应该分配的宽度 heightForHeaderInSection
和heightForFooterInSection
- 然后取得头节点尾节点视图
viewForHeaderInSection
和viewForFooterInsection
(如果实现的话) - 再次调用
heightForRowAtIndexPath
方法 willDisplayHeaderView
和willDIsplayFooterView
方法
如果一个tableView不会显示在视图中,那么方法之后执行到numberOfRowsInSection
就停止,不会进行剩余的步骤来影响性能
折叠cell
折叠cell是为了简化用户界面,隐藏在通常情况下不需要的部分的一种方法,该方法符合渐进展开原则
在普通用户不需要过多的复杂选项或者信息,或者在需要选择某种风格之类的枚举值的时候可以考虑使用折叠cell
我们一般所说的折叠cell,实际上是在代理方法中,更换tableView的cell数量,来隐藏一部分的cell,在需要的时候,再展示的一个方法
为了在协议中更改cell的数量,我们可以使用一个枚举或者就是简单的布尔值来判断tableView是否展开,从而给tableView返回cell的个数
基本流程
更改流程:
- 使用一个按钮(可以是tableView的一个cell本身,或者在头视图上添加一个专门用来展开的按钮)来控制是否展开的布尔值
- 在按钮改变后,重新加载tableView剩下的事tableView会处理!
tableView的流程
- 正常加载tableView
- 在tableView中读取布尔值,根据布尔值来判断cell是否被展开从而渲染cell
- 展示
这就是基本的折叠cell的展开流程,我们写一个小demo来展示一下
实战演练
由于代码简单我这里就不使用MVC结构了,直接用View来处理model的数据存储
ViewController.h
#import <UIKit/UIKit.h>#import "FoldAndExtendProtocol.h"
#import "PMHeaderView.h"@class PMFoldCellView;@interface ViewController : UIViewController <UITableViewDelegate,UITableViewDataSource,FoldAndExtendProtocol>
@property (nonatomic, strong)PMFoldCellView* mainView;
@property (nonatomic, strong)PMHeaderView* HeaderView;
@property (nonatomic, strong)NSArray* array1;
@property (nonatomic, strong)NSArray* array2;@property (nonatomic, assign)BOOL isExtend;@end
其中PMHeaderView
内部只有一个tableView的属性,FoldAndExtendProtocol
声明了- (**void**)extendCell;
这个方法用来控制tableView是否展开
ViewController.m
... // 初始化函数,填充了内容数组,并设置了基本的代理和约束
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {// 根据属性的布尔值来确定当前是否处于展开状态if (self.isExtend) {return 5;} else {return 1;}}
... //设置高度
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// NSLog(@"cellForRowAtIndexPath");// 不使用自定义cell,使用系统的默认样式UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:@"MyCell"];if (cell == nil) {cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Mycell"];}// 根据不同的状态来读取不同的数据源if (self.isExtend) {cell.textLabel.text = self.array1[indexPath.row];} else {cell.textLabel.text = self.array2[indexPath.row];}// 在第一个cell中添加控制展开收起的按钮if (indexPath.row == 0) {UIButton* btnExtend = [[UIButton alloc] init];[cell.contentView addSubview:btnExtend];[btnExtend mas_makeConstraints:^(MASConstraintMaker *make) {make.right.equalTo(cell.contentView.mas_right).offset(-10);make.centerY.equalTo(cell.contentView);}];// 根据状态来展示不同状态的按钮if (self.isExtend) {[btnExtend setBackgroundImage:[UIImage systemImageNamed:@"chevron.down"] forState:UIControlStateNormal];} else {[btnExtend setBackgroundImage:[UIImage systemImageNamed:@"chevron.up"] forState:UIControlStateNormal];}[btnExtend addTarget:self action:@selector(extendCell) forControlEvents:UIControlEventTouchUpInside];}return cell;
}- (void) extendCell {// 切换当前状态,然后刷新整个tableViewself.isExtend = !self.isExtend;
// NSLog(@"点按按钮");[self.mainView.tableView reloadData];}
效果展示: