TableView怎么用
TableView中可以添加TableCell,而其主要通过两个协议进行Table的管理 <UITableViewDataSource,UITableViewDelegate>,可以通过阅读头文件详细了解
UITableViewDataSource
该协议中的两个函数是Table管理Cell必须的,分别是Table有多少行和每行是什么Cell
@required
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
UITableViewDelegate
这个协议中是主要定义了cell的选中功能函数,也包括一些其它optional功能,如果仅仅是展示性质的cell,可以不用用到
// Selection
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
TableView中Cell的复用
TableView中cell的复用是十分十分重要的一个知识点,几乎所有面试都会问吧
什么叫复用
就是我有100行cell,但是不可能一页(Screen的高度)显示完,那么我可以制造一种假象,仿佛我有100行,但是实际只有20行,每当用户进行滑动,我就把滑出屏幕的cell,重新拼接到屏幕下方,展示给用户
不复用的实现
首先看不采用复用方法的Cell生成,遵循UITableViewDataSource生成cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
NSString *cellIdentifier = [NSString stringWithFormat:@"cell%tu",indexPath.row];
UITableViewCell *cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
return cell;
}
由以上函数可知,这是传统思维,给予每个cell一个identifer然后通过后缀的行数返回给Table每个cell,这样如果我有100行,我就有100个cell在内存里,这样无疑是十分消耗内存的
复用的实现
复用就是,我使用一个cellIdentifer展示100个cell,那么就要用到**dequeueReusableCellWithIdentifier:**函数
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *cellIdentifier = @"cellID";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
return cell;
}
以上的复用过程主要过程是
- 我在静态区声明一个cellIndentifer,不用每次执行到这里都初始化一个NSString
- 然后用dequeueReusableCellWithIdentifier:函数根据Indentifer从一个复用池(cocoa框架自带的)里取cell
- 如果取不到(cell == nil),就重新初始化一个
那么如果采用复用方法,100行的cell会发生什么
- 假设一屏有10行
- 不可否认的是我至少需要10个长的一样的cell
- 那么前10行通过tableView:cellForRowAtIndexPath:时,都会因为复用池中没有identifer为”cellID”的cell从而去初始化
- 此时用户下滑,第1行移出屏幕,第11行移入屏幕
- 第1行移出屏幕,identifer为”cellID”的一个cell进入复用池
- 第11行移入屏幕时,经过tableView:cellForRowAtIndexPath:内时,通过dequeueReusableCellWithIdentifier:函数从复用池中取出刚刚第1行放入的cell,完成复用
- 如果此时又上滑,第11行移出屏幕,cell被放回复用池又被第一行取走
需要注意的是,通常为了保障动画的流畅,10行可能需要12-15个cell进行复用
Cell也可以用在普通View中
由于Cell本身就是一个View,所以不一定非得加载在Table中,普通的View也可以直接用
UITableViewCell *cell = [[UITableViewCell alloc]init];
[self.view addSubview:cell];
但是由于其不在UITableViewDelegate的tableView:didSelectRowAtIndexPath:中实现选中功能,所以其本身不能交互,需要进行设置
[cell setUserInteractionEnabled:YES];
而且又由于其不是button,并不能touchUpInside,所以需要通过添加手势来交互
UITapGestureRecognizer *gestureOnCell = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapGestureOnAlbumCell:)];
[cell addGestureRecognizer:gestureOnCell];
感觉并不好用呢╮<(=╯-╰=)>╭ 但是可以省去自定义view,可以利用系统的样式,减少开发工作
[cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
[cell.textLabel setText:@"cellTitle"];
[cell.imageView setImage:[UIImage imageNamed:@"account_headImg_picture"]];