UITableView基本使用
展示多组数据
#import "ViewController.h"
@interface ViewController () <UITableViewDataSource>
@property (nonatomic, weak) IBOutlet UITableView *tableView;
@end
@implementation ViewController
-(void)viewDidLoad
{
[super viewDidLoad];
self.tableView.dataSource = self;
}
//告诉TableView一共有多少组
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 4; //展示4组数据
}
//告诉TableView第section组有多少行
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(section == 0){
//第0组有多少行
return 2;
}else if(section == 1){
return 6;
}else if (section == 2){
return 6;
}else {
return 1;
}
}
//告诉tableView每一行显示的内容(tableView每一行都是UITableViewCell或者它的子类)
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [[UITableViewCell alloc] init];
if(indexPath.section == 0 && indexPath..row == 0){
cell.imageView.image = [UIImage imageNamed:@"123"];
cell.accessoryView = [[UISwitch alloc] init]; //设置右侧为开关
cell.accessoryType = UITableViewCellAccessoryDisclosureIndictor; //设置右侧为箭头
//注意:accessoryView比accessoryType优先级要高
cell.textLabel.text = @"通用";
}else {
cell.textLabel.text = @"隐私";
}
return cell;
}
//设置每一组的头部标题
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
if(section == 0){
return @"日系品牌";
}else{
return @"djjhhg";
}
}
//设置每一组的尾部标题,如果标题过长,会自动换行
-(NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
{
if(section == 0){
return @"日系品牌";
}else{
return @"djjhhg";
}
}
@end
展示单组数据
//告诉TableView一共有多少组
//如果不实现默认就是1组
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1; //展示单组数据
}
UITableView的常见属性
//行高
self.tableView.rowHeight = 44; //默认44
//设置tableView每一组的头部高度
self.tableView.sectionHeaderHeight = 80;
self.tableView.sectionFooterHeight = 90;
self.tableView.separatorColor = [UIColor redColor]; //如果设置成**clearColor**就可以隐藏分割线
self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine; //默认单行线
self.tableView.tableHeaderView = [[UISwitch alloc] init]; //整张表的头部 表头控件
self.tableView.tableFooterView = [[UISwitch alloc] init]; //整张表的尾部 表尾控件
UITableViewCell的常见属性
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.accessoryView
cell.selectionStyle = UITableViewCellSelectionStyleBlue; //设置选中的颜色
cell.selectedBackgroundView = [[UIView alloc] init]; //设置选中的背景图片
cell.backgroundColor = [UIColor redColor]; //设置背景颜色
cell.backgroundView = [[UIView alloc] init]; //设置背景 优先级大于backgroundColor
cell的contentView
contentView是cell的子控件,而其他控件实际上都是contentView的子控件
UITableView的代理方法
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//选中某一行就会调用这个方法
}
-(void)tableView:(UITableView *)tableView didDeSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//取消选中某一行调用这个方法
}
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
//这个方法返回每一组的头部控件,实现该方法后,-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section这个方法就不好使了
}
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
//这个方法设置每一组的头部高度,可以分别设置每一组的头部高度
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
//分别设置每一行的行高
}
UITableViewController的基本使用
UITableViewController已经遵守了UITableViewDelegate和UITableViewDataSource协议
因此,在UITableViewControll中,我们只需要实现数据源方法和代理方法即可。
在UITableViewController中,self.view和self.tableView指向同一个对象。
UITableView的性能优化
当cell数量很多的时候,我们并不需要一开始就创建出所有的cell,因为并不是所有的cell都会被用户看到,所以cell只需要在适当的时候显示即可。而这一点苹果已经帮我们实现了,苹果的实现方法是,只有当cell要被用户看到了,才会加载这个cell。
而苹果没有帮我们实现的是,当我们往前滚动,想要看之前的数据时,这时这些cell明明已经被创建过了,但是当我们往前滚动时,又会被创建一遍。因此,这里需要我们实现优化。
苹果的实现原则是:每当一个cell进入到视野范围时,就会被调用一次。
解决问题思路:
将已经创建过,但是却已经不在视野中的cell,放到缓存池中,下次再创建新的cell时,先看缓存池中是否有缓存的cell,若有的话,则只需要将缓存池的cell拿过来直接用即可。
但是真正在使用的过程中,缓存池中并不一定只有一个类型的cell,所以需要为每一种类型cell做一个标记。
这样做的好处是:内存中的cell只有固定的数量,而不会无限的创建cell。
-(void)viewDidLoad{
[super viewDidLoad];
//注册对应的cell类型为UITableViewCell,当缓存池中没有相应的cell时,这时UITableView会根据标识自动找到注册的UITableViewCell类型,然后自动创建相应类型的UITableViewCell对象。
//用注册这种方法的不好的地方就是不能创建其他的样式,比如说subtitle。这种方式更适用于自定义cell控件。
[tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:ID];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//去缓存池中取是否有可循环用的cell
static NSString *ID = @"A"; //static只修改生命周期,不修改作用域
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
/*
if(cell == nil){
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
cell.backgroundColor = [UIColor redColor];
}
*/
//注意:所有cell都一样的样式或特性可以卸载if语句中,但是如果cell的样式并不都一样,则不能写在if语句中。重复利用的cell可能会带来一个问题,就是数据源的混乱。
//小技巧,有if就有else
return cell;
}
添加索引
-(NSArray<NSString *>)sectionIndexTitlesForTableView:(UITableView *)tableView{
return @[@"A",@"B",@"C",@"D"]; //按组索引
}
XMGTableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
UITableView方法的调用顺序
heightForRowAtIndexPath------ 确定cell高度
cellForRowAtIndexPath ---- 返回每一个cell
执行自控件中的方法 initWithFrame layoutSubview