UITableView是UIKit中最常用的一种视图,是UIScrollView的子类

本篇文章介绍 UITableView的基本使用,包括:

UITableView的数据源驱动

各种数据源、代理方法

单元格的重用机制

数据的刷新

...




UITableView的样式

创建时需要指定样式:

-(instancetype)initWithFrame:(CGRect)framestyle:(UITableViewStyle)style@property(nonatomic,readonly)UITableViewStylestyletypedefenum{UITableViewStylePlain,UITableViewStyleGrouped}UITableViewStyle;


UITableView中的内容

表格视图中可以包含多个组

每个组中又可以包含多个单元格(cell)

每个组上面的header视图

每个组下面的footer视图


这些属性的赋值:使用数据源和代理驱动


UITableView的数据源驱动

UITableView包含两个代理:

@property(nonatomic,assign)id<UITableViewDelegate>delegate//代理@property(nonatomic,assign)id<UITableViewDataSource>dataSource//数据源

数据源可以使用代理设计模式,其功能属于代理的第三种应用,为自身属性赋值


重要的数据源方法:

表格视图中应当包含多少个组,默认为1

-(NSInteger)numberOfSectionsInTableView:(UITableView*)tableView

表格视图中指定组中应当包含多少个cell,必须实现

-(NSInteger)tableView:(UITableView*)tableViewnumberOfRowsInSection:(NSInteger)section

表格视图中指定组及行的cell视图,必须实现

-(UITableViewCell*)tableView:(UITableView*)tableViewcellForRowAtIndexPath:(NSIndexPath*)indexPath

表格视图中的cell视图在将要显示时自动调用,应将数据绑定的代码放在这里

-(void)tableView:(UITableView*)tableViewwillDisplayCell:(UITableViewCell*)cellforRowAtIndexPath:(NSIndexPath*)indexPath

一般来说,这四个数据源方法,是必须要实现的(第一个不实现默认为一个section)


如:

//当前控制器遵循数据源、代理协议@interfaceViewController()<UITableViewDataSource,UITableViewDelegate>

//当前控制器成为tableView的数据源和代理self.tableView.dataSource=self;self.tableView.delegate=self;

//四个数据源方法-(NSInteger)numberOfSectionsInTableView:(UITableView*)tableView{return3;//三个section}-(NSInteger)tableView:(UITableView*)tableViewnumberOfRowsInSection:(NSInteger)section{returnsection+1;}-(UITableViewCell*)tableView:(UITableView*)tableViewcellForRowAtIndexPath:(NSIndexPath*)indexPath{UITableViewCell*cell=[[UITableViewCellalloc]initWithStyle:UITableViewCellStyleDefaultreuseIdentifier:@"111"];returncell;}-(void)tableView:(UITableView*)tableViewwillDisplayCell:(UITableViewCell*)cellforRowAtIndexPath:(NSIndexPath*)indexPath{cell.textLabel.text=[NSStringstringWithFormate:@"Section:%ldRow:%ld",indexPath.section,indexPath.row];}


UITableView的行高

两种方式:

1)统一的高度通过UITableView对象的rowHeight属性设定

@property(nonatomic)CGFloatrowHeight

2)也可以通过实现tableView的代理方法,返回每一行的高度

-(CGFloat)tableView:(UITableView*)tableViewheightForRowAtIndexPath:(NSIndexPath*)indexPath


UITableView的其他数据源、代理方法

行被点击(选择)

-(void)tableView:(UITableView*)tableViewdidSelectRowAtIndexPath:(NSIndexPath*)indexPath

section的右侧索引

-(NSArray<NSString*>*)sectionIndexTitlesForTableView:(UITableView*)tableView

section的header和footer

//header、footer上的文字-(NSString*)tableView:(UITableView*)tableViewtitleForHeaderInSection:(NSInteger)section-(NSString*)tableView:(UITableView*)tableViewtitleForFooterInSection:(NSInteger)section//header、footer为自定义的视图-(UIView*)tableView:(UITableView*)tableViewviewForHeaderInSection:(NSInteger)section-(UIView*)tableView:(UITableView*)tableViewviewForFooterInSection:(NSInteger)section//header、footer的高度-(CGFloat)tableView:(UITableView*)tableViewheightForHeaderInSection:(NSInteger)section-(CGFloat)tableView:(UITableView*)tableViewheightForFooterInSection:(NSInteger)section

编辑模式

//返回每个cell的编辑状态的模式(删除、插入)-(UITableViewCellEditingStyle)tableView:(UITableView*)tableVieweditingStyleForRowAtIndexPath:(NSIndexPath*)indexPath//响应点击编辑按钮时的动作-(void)tableView:(UITableView*)tableViewcommitEditingStyle:(UITableViewCellEditingStyle)editingStyleforRowAtIndexPath:(NSIndexPath*)indexPath

编辑模式有两种方式进入:

1)滑动单元格,当前单元格进入编辑模式

2)修改UITableView对象的editing属性

@property(nonatomic,getter=isEditing)BOOLediting//编辑模式使能-(void)setEditing:(BOOL)editinganimated:(BOOL)animate



单元格的重用机制

为了有效的利用内存,UITableView使用了重用机制管理其内部显示的所有cell

当一个cell离开了屏幕范围时,会将其从tableView内部移除并放到一个缓存队列中存储

当一个cell将要显示时,如果队列中存在cell,则直接重用该cell,如果没有则创建新的

这个队列称之为“重用队列”,这种管理内部视图的方式称之为“重用机制”

重用ID:

一个tableView中可以存在多种不同样式的cell,引入重用ID以区分不同的样式

即:从重用队列取cell时,要按照指定的ID取出,创建cell时要设置其ID


从重用队列取出cell的方法:(UITableView)

-(id)dequeueReusableCellWithIdentifier:(NSString*)identifier

将上面返回cell的数据源方法修改为:

-(UITableViewCell*)tableView:(UITableView*)tableViewcellForRowAtIndexPath:(NSIndexPath*)indexPath{staticNSString*cellID=@"cell";UITableViewCell*cell=[tableViewdequeueResuableCellWithIdentifier:cellID];if(cell==nil){cell=[[UITableViewCellalloc]initWithStyle:UITableViewCellStyleDefaultreuseIdentifier:@"111"];}returncell;}


UITableView数据的重新加载

在实际开发中,触发了某些事件(如网络获取到更多数据、用户请求刷新等),要求UITableView刷新显示所有数据

刷新的方法如下:

-(void)reloadData-(void)reloadRowsAtIndexPaths:(NSArray*)indexPathswithRowAnimation:(UITableViewRowAnimation)animation-(void)reloadSections:(NSIndexSet*)sectionswithRowAnimation:(UITableViewRowAnimation)animation-(void)reloadSectionIndexTitles//重新加载右侧的索引

这些方法将重新调用全部或部分的数据源、代理方法,重新展示数据


重新加载数据的通常做法是:

控制器实现UITableView的数据源和代理方法,并管理着需要显示的数据模型(数组)

当需要刷新数据时,控制器修改数据模型(数组),然后调用UITableView的刷新方法

即:修改模型 --> reloadData



UITableView的其他的属性及方法

UITableView的背景视图(通常设置一个UIImageView对象)

@property(nonatomic,readwrite,retain)UIView*backgroundView

滚动到指定的单元格

-(void)scrollToRowAtIndexPath:(NSIndexPath*)indexPathatScrollPosition:(UITableViewScrollPosition)scrollPositionanimated:(BOOL)animated

单元格之间的分割样式及颜色

@property(nonatomic)UITableViewCellSeparatorStyleseparatorStyle@property(nonatomic,retain)UIColor*separatorColor

单元格与indexPath的互相获取

-(UITableViewCell*)cellForRowAtIndexPath:(NSIndexPath*)indexPath-(NSIndexPath*)indexPathForCell:(UITableViewCell*)cell

获得当前显示的单元格

-(NSArray*)visibleCells//获得所有可见的cell-(NSArray*)indexPathsForVisibleRows//获得所有可见cell的indexPath

选择相关设置

@property(nonatomic)BOOLallowsSelection//cell选择的使能@property(nonatomic)BOOLallowsMultipleSelection//多选使能-(NSIndexPath*)indexPathForSelectedRow//当前被选择的cell的indexPath-(NSArray*)indexPathsForSelectedRows//多选时-(void)selectRowAtIndexPath:(NSIndexPath*)indexPathanimated:(BOOL)animatedscrollPosition:(UITableViewScrollPosition)scrollPosition//选择指定行-(void)deselectRowAtIndexPath:(NSIndexPath*)indexPathanimated:(BOOL)animated//反选