IOS开发中UITableView(表视图)的滚动优化及自定义Cell
IOS 开发中UITableView是非常常用的一个控件,我们平时在手机上看到的联系人列表,微信好友列表等都是通过UITableView实现的。UITableView这个控件中的列表的每一行是一个cell,当UITableView中cell数量特别大的时候,由于每次都需要alloc分配内存并初始化,会导致app运行不流畅,所以可以使用苹果提供的几个方法进行优化,我把这个过程记录下来供自己以后查阅。
当然,既然说到优化,那我们就从没有优化的状态开始谈起。先使用最基本的流程实现一个UITableView(表视图),然后再谈优化,以及自定义。
本文正文主要分一下三步:
一、使用最基本的流程来实现一个表视图。
二、通过滚动优化表视图中cell的创建使之节约内存。
三、自定义表视图中cell样式。
一、使用最基本的流程来实现一个表视图:
文章一开始说了UITableView这个控件中的列表的每一行是一个cell,所以我们先创建一个UITableView表视图,然后在datasource代理方法中返回cell的个数,以及创建cell:
1、创建UITableView控件myTableView,全局变量、设置代理、添加到当前view:
1 #import "ViewController.h" 2 3 @interface ViewController (){ 4 UITableView *myTableView; 5 } 6 @end 7 8 @implementation ViewController 9 10 - (void)viewDidLoad { 11 [super viewDidLoad]; 12 13 myTableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 20, 414, 600)]; 14 myTableView.backgroundColor = [UIColor lightGrayColor]; 15 myTableView.delegate = self; 16 myTableView.dataSource = self; 17 18 [self.view addSubview:myTableView]; 19 }
2、在头文件中添加代理:
1 // 2 // ViewController.h 3 // UITableView列表 4 // 5 // Created by mac on 16/4/15. 6 // Copyright © 2016年 mzw. All rights reserved. 7 // 8 9 #import <UIKit/UIKit.h> 10 11 //添加代理UITableViewDataSource和UITableViewDelegate 12 @interface ViewController : UIViewController<UITableViewDataSource,UITableViewDelegate> 13 14 15 @end
3、进入UITableViewDataSource中找到代理方法并粘贴到.m文件中,实现方法,其中:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 返回一个数字,是cell的个数;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 返回的是UITableViewCell,所以我们就在这个函数中创建cell,并返回,这样就实现了代理方法。
具体代码:
1 //myTableView的行数 2 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ 3 return 10; 4 } 5 6 7 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ 8 // 创建UITableViewCell 9 UITableViewCell *cell = [[UITableViewCell alloc]init]; 10 // UITableViewCell自带textlabel,indexPath.row为行数 11 cell.textLabel.text = [NSString stringWithFormat:@"这是第%ld行",indexPath.row]; 12 return cell; 13 }
以上代码的第9行创建了UITableViewCell并初始化,第11行是给cell自带的textlabel设置文字的,这样的做法就是:需要多少个cell,就alloc多少次,如果软件需要的cell个数太多,会导致下拉时非常卡。但是在需要展示的数据量很小,也就是需要的cell不多的时候,可以使用这种方式。
通过这种方式实现的表视图模拟如下:
二、通过优化表视图中cell的创建使之节约内存。
滚动优化的原理就是如果这个屏幕上能显示10个cell,那我就创建11个cell,不管有多少数据要现实,就用这11个cell。当用户上拉或下拉的时候,上面消失的cell将重新装入要显示的数据,然后显示在屏幕上,相当于总有一个在缓冲等待显示。通过这样的方式减少了cell的alloc次数,进而降低了内存开销,提高了系统性能。
要实现以上思路,只需要把一中的创建cell的代码换成一下语句:
1 // // 2、使用队列池优化方式创建cell 2 static NSString *cellid = @"cell";//一个固定的标识 3 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellid]; 4 if (cell == nil) { 5 cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellid]; 6 }
三、自定义表视图中cell样式:
1、先新建一个继承自UITableViewCell的类,我这里创建的名称是myTableViewCell,创建的时候勾选创建nib文件。
2、打开创建好的nib文件,然后里面已经有一个cell了,我们采用拖拽的办法给这个cell里加入一个UIImageView,然后给里面放置一个图片,在这里我使用一张黄色的纯色图片,然后在cell的左边拖入一个buttom,右边拖入一个label,完成后如下图:
3、在 myTableViewCell.h中定义两条语句
1 @property(nonatmic, strong)IBOUTLET UIButton *mybutton; 2 @property(nonatmic, strong)IBOUTLET UILabel *mylabel;
写完这两句之后就可以在nib中拖线连接关系了,这个过程是最基本的,这里不说。
4、在ViewController.m中完成app 的主要功能,也就是表视图的实现:
1 // 2 // ViewController.m 3 // UITableView使用nib拖动自定义 4 // 5 // Created by mac on 16/4/15. 6 // Copyright © 2016年 mzw. All rights reserved. 7 // 8 9 #import "ViewController.h" 10 #import "myTableViewCell.h" 11 12 @interface ViewController (){ 13 UITableView *myTableView; 14 NSArray *contentArray; 15 } 16 17 @end 18 19 @implementation ViewController 20 21 - (void)viewDidLoad { 22 [super viewDidLoad]; 23 24 myTableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 20, 414, 500)]; 25 26 myTableView.delegate = self; 27 myTableView.dataSource = self; 28 [self.view addSubview:myTableView]; 29 30 31 // 用来为cell的mulabel赋值的数组 32 contentArray = @[@"one",@"two",@"three",@"four",@"five",@"six",@"seven",@"eight",@"nine",@"ten",]; 33 34 } 35 36 37 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ 38 // 设置cell的数量为数组的元素个数 39 return contentArray.count; 40 } 41 42 43 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ 44 45 // 优化方式创建cell 46 static NSString *cellid = @"cell"; 47 myTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellid]; 48 49 if (cell == nil) { 50 51 // 使用绘制好的nib为cell赋值 52 cell = (myTableViewCell*)[[[NSBundle mainBundle]loadNibNamed:@"myTableViewCell" owner:self options:nil] objectAtIndex:0]; 53 54 // cell上按钮的button,为了从cell上的多个控件中区分出某个button 55 cell.mybutton.tag = 1000; 56 57 // 为cell上的button添加方法 58 [cell.mybutton addTarget:self action:@selector(haha:) forControlEvents:UIControlEventTouchUpInside]; 59 60 // 使用数组的内容为cell赋值 61 cell.mylabel.text = [contentArray objectAtIndex:[indexPath row]]; 62 } 63 64 65 66 67 return cell; 68 69 } 70 71 72 //拿到cell,然后根据tag拿到button然后输出buttn上的文字 73 -(void)haha:(UIButton*)sender{ 74 // button在cell的content上,所以通过以下方法获取 75 myTableViewCell *cell =(myTableViewCell*)[[sender superview]superview]; 76 UIButton *mybutton = (UIButton*)[cell viewWithTag:1000]; 77 NSLog(@"%@",mybutton.titleLabel.text); 78 } 79 80 81 - (void)didReceiveMemoryWarning { 82 [super didReceiveMemoryWarning]; 83 // Dispose of any resources that can be recreated. 84 } 85 86 @end
模拟效果如下:
以上。