UITableView是UIKit中最常用的一种视图,是UIScrollView的子类
本篇文章介绍 UITableView的基本使用,包括:
UITableView的数据源驱动
各种数据源、代理方法
单元格的重用机制
数据的刷新
...
UITableView的样式
创建时需要指定样式:
- (instancetype)initWithFrame:(CGRect)frame style:(UITableViewStyle)style
@property(nonatomic, readonly) UITableViewStyle style
typedef enum {
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 *)tableView numberOfRowsInSection:(NSInteger)section
表格视图中指定组及行的cell视图,必须实现
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
表格视图中的cell视图在将要显示时自动调用,应将数据绑定的代码放在这里
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
一般来说,这四个数据源方法,是必须要实现的(第一个不实现默认为一个section)
如:
//当前控制器遵循数据源、代理协议
@interface ViewController () <UITableViewDataSource, UITableViewDelegate>
//当前控制器成为tableView的数据源和代理
self.tableView.dataSource = self;
self.tableView.delegate = self;
//四个数据源方法
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 3;//三个section
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return section+1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell * cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"111"];
return cell;
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
cell.textLabel.text = [NSString stringWithFormate:@"Section:%ld Row:%ld", indexPath.section, indexPath.row];
}
UITableView的行高
两种方式:
1)统一的高度通过UITableView对象的rowHeight属性设定
@property(nonatomic) CGFloat rowHeight
2)也可以通过实现tableView的代理方法,返回每一行的高度
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
UITableView的其他数据源、代理方法
行被点击(选择)
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath
section的右侧索引
- (NSArray<NSString *> *)sectionIndexTitlesForTableView:(UITableView *)tableView
section的header和footer
//header、footer上的文字
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
//header、footer为自定义的视图
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
//header、footer的高度
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
编辑模式
//返回每个cell的编辑状态的模式(删除、插入)
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
//响应点击编辑按钮时的动作
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath*)indexPath
编辑模式有两种方式进入:
1)滑动单元格,当前单元格进入编辑模式
2)修改UITableView对象的editing属性
@property(nonatomic, getter=isEditing) BOOL editing //编辑模式使能
- (void)setEditing:(BOOL)editing animated:(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 *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellID = @"cell";
UITableViewCell * cell = [tableView dequeueResuableCellWithIdentifier:cellID];
if ( cell == nil ) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"111"];
}
return cell;
}
UITableView数据的重新加载
在实际开发中,触发了某些事件(如网络获取到更多数据、用户请求刷新等),要求UITableView刷新显示所有数据
刷新的方法如下:
- (void)reloadData
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
- (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation
- (void)reloadSectionIndexTitles //重新加载右侧的索引
这些方法将重新调用全部或部分的数据源、代理方法,重新展示数据
重新加载数据的通常做法是:
控制器实现UITableView的数据源和代理方法,并管理着需要显示的数据模型(数组)
当需要刷新数据时,控制器修改数据模型(数组),然后调用UITableView的刷新方法
即:修改模型 --> reloadData
UITableView的其他的属性及方法
UITableView的背景视图(通常设置一个UIImageView对象)
@property(nonatomic, readwrite, retain) UIView *backgroundView
滚动到指定的单元格
- (void)scrollToRowAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UITableViewScrollPosition)scrollPosition animated:(BOOL)animated
单元格之间的分割样式及颜色
@property(nonatomic) UITableViewCellSeparatorStyle separatorStyle
@property(nonatomic, retain) UIColor *separatorColor
单元格与indexPath的互相获取
- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath
- (NSIndexPath *)indexPathForCell:(UITableViewCell *)cell
获得当前显示的单元格
- (NSArray *)visibleCells //获得所有可见的cell
- (NSArray *)indexPathsForVisibleRows //获得所有可见cell的indexPath
选择相关设置
@property(nonatomic) BOOL allowsSelection //cell选择的使能
@property(nonatomic) BOOL allowsMultipleSelection //多选使能
- (NSIndexPath *)indexPathForSelectedRow //当前被选择的cell的indexPath
- (NSArray *)indexPathsForSelectedRows //多选时
- (void)selectRowAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animatedscrollPosition:(UITableViewScrollPosition)scrollPosition //选择指定行
- (void)deselectRowAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated //反选
转载于:https://blog.51cto.com/annmeng/1746269