概述:
UITableViewController 即对UIVIewController和tableView的综合封装,因此其功能也多是两者的综合.其功能主要分为三个部分: 视图控制器部分/表示图部分/本身特有功能
一 本身特有功能
initWithStyle: | 初始化时,需要制定类型 |
(UITableVIew *) tableView | 视图控制器所管理的视图 |
(BOOL )clearsSelectionOnViewWillAppear | 决定视图控制器在即将显示时,是否清空选择状态, 默认时YES |
(UIRefreshControl *)refreshControl | 此属性为默认为nil, 作为下拉刷新的控件,需要时,显示在视图控制器顶部,如果想要通过他实现一些功能, 则需要手动为其添加行为.作为继承与UIControl的控件,其事件类型为UIControlEventValueChanged |
二 表视图部分 UITableView
概述:
* UITableView继承自UIScrollView 通过典型的 MVC模式 完成了界面的逐条展示功能.
* UITableView的结构UITableView由头部,尾部,和中间一连串的单元格组成, UITableView的头部由tableHeaderView属性设置, 尾部由 tableFooterView属性设置, 中间的行高可通过rowHeight属性设置
* UITableView提供好了两种样式: UITableViewStylePlain 和 UITableViewStyleGrouped
* 通过UITableView提供了丰富的界面展示功能 --- UITableViewCell本身就提供了四种样式的选择, 并且可以通过义继承UITableViewCell完成自定义单元格
* 通过代理实现的编辑功能实现丰富的单元格操作功能(增加/ 删除/ 添加)
* UTableView的单元格创建采用重用机制, 实现了性能的优化(注: 重用机制实现的两种方式)
* UITableView的使用步骤为:
1> 表示图对象的创建(初始化时设置风格);
2> 单元格基本属性的设置(分割线/ 数据源代理/ 代理/ 行高/);
3> 实现代理协议(通过代理协议设置单元格,完成单元格的自定义操作/ 通过代理协议实现单元格的编辑功能 / 通过代理协议实现单元格的其他功能添加)
苹果官方API 文档对于UITableView的描述
1. 首先是tableView展示的内容的描述
A table view displays a list of items in a single column.
UITableView
is a subclass of
UIScrollView(UITableView是UIScrollerView的子类,且仅展示一列信息条,且只支持垂直方向的的滑动)
The cells comprising the individual items of the table are
UITableViewCell
objects;
UITableView
uses these objects to draw the visible rows of the table
(UITableView 通过UITableViewCell展示每一行的信息)
Cells have content—titles and images—and can have, near the right edge, accessory views.
(UITableViewCell官方提供的类型 具有title/image/right edge/accessory 属性)
Accessory views can also be framework controls, such as switches and sliders, or can be custom views.(附加视图还可以使用系统提供的控制类控件,例如 switch/selder ,或者自定义的视图)
Table views can enter an editing mode where users can insert, delete, and reorder rows of the table
(UITableView还提供了编辑模式, 供用户进行插入/删除/移动单元格的操作)
A table view can have an index that appears as a bar on the right hand side of the table (for example, "A" through "Z").
You can touch a particular label to jump to the target section.
(UITableView 还提供了一个右侧索引 例如(展示 “A”到”Z”,你可以通过点击指定的label 跳转到制定的section
)
UITableView
declares a category on
NSIndexPath
that enables you to get the represented row index (
row
property) and section index (
section
property)
(UITableView 还声明了一个分类NSIndexPath 用于表示 index 和 section属性)
A
UITableView
object must have an object that acts as a data source and an object that acts as a delegate;
(UITableView 必须有一个代理执行他的两个协议
1. table基本介绍
1.1 常用属性
基本属性:(配置单元格) | |
返回单元格数量
|
- (NSInteger)numberOfSections
返回分组数量
|
@property(nonatomic) CGFloat rowHeight
单元格高度
|
@property(nonatomic) UITableViewCellSeparatorStyle separatorStyle
分割线类型
|
@property(nonatomic, retain) UIColor *separatorColor
分割线颜色
|
@property(nonatomic, readwrite, retain) UIView *backgroundView
表视图背景视图
|
@property(nonatomic) UIEdgeInsets separatorInset
全局分割线缩进, 适用于iOS7之后, 只能影响到左右缩进
| |
@property(nonatomic, retain) UIView *tableFooterView
表视图底部的辅助视图
|
@property(nonatomic, retain) UIView *tableHeaderView
表视图顶部的辅助视图
|
@property(nonatomic) CGFloat sectionHeaderHeight
组头视图的高度
|
@property(nonatomic) CGFloat sectionFooterHeight
组尾的高度
|
基本方法 | |
- (void)registerClass:(Class)
cellClass
forCellReuseIdentifier:(NSString *)
identifier
为指定重用标示符指定单元格类型
|
- (id)dequeueReusableCellWithIdentifier:(NSString *)
identifier
forIndexPath:(NSIndexPath *)
indexPath
根据重用标示符获取重用单元格
|
- (void)reloadData
数据更新
|
@property(nonatomic, assign) id< UITableViewDataSource > dataSource
@property(nonatomic, assign) id< UITableViewDelegate > delegate
|
- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)
indexPath
- (NSIndexPath *)indexPathForCell:(UITableViewCell *)
cell
指定下标的单元格
|
@property(nonatomic, getter=isEditing) BOOL editing
- (void)setEditing:(BOOL)
editing
animated:(BOOL)
animate
是否进入编辑模式
|
高级方法 | |
- (UITableViewHeaderFooterView *)headerViewForSection:(NSInteger)
section
自定义组头视图
|
- (UITableViewHeaderFooterView *)footerViewForSection:(NSInteger)
section
自定义组尾视图
|
- (NSIndexPath *)indexPathForRowAtPoint:(CGPoint)
point
获取表视图上指定位置的单元格下标
|
- (NSArray *)visibleCells
- (NSArray *)indexPathsForVisibleRows
所有可视的单元格
|
- (NSIndexPath *)indexPathForSelectedRow
- (NSArray *)indexPathsForSelectedRows
返回当前选中的单元格的位置
|
@property(nonatomic) BOOL allowsSelection
@property(nonatomic) BOOL allowsMultipleSelection
@property(nonatomic) BOOL allowsSelectionDuringEditing
@property(nonatomic) BOOL allowsMultipleSelectionDuringEditing
是否允许选中/ 多个选中
|
注: 重用机制的两种实现 iOS5 之前的重用实现方法
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// UITableViewCell *aCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil]; // aCell.textLabel.text = self.datesoure[indexPath.row]; // aCell.imageView.image = [UIImage imageNamed:@“gmx1”]; // return [aCell autorelease]; //1 定义静态重用标识符 static NSString *indentifier = @“CELL”; //2 根据重用标识符从表视图的重用队列中获取可被重用的单元格 UITableViewCell *aCell = [tableView dequeueReusableCellWithIdentifier:indentifier]; //3 如果重用队列里并无可重用单元格 , 则创建单元格对象 ( 常见用于表视图刚刚开始布局单元格时 , 这时并没有产生重用 ) if (!aCell) { // 此时执行 autorelease -> 谁创建 谁释放 / 不能在返回时 autorelease aCell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:indentifier]autorelease]; } //4 为单元格添加数据 aCell.textLabel.text = [NSString stringWithFormat:@“%@ - %ld”,aCell.textLabel.text,indexPath.row]; NSLog(@“%@“,aCell.textLabel.text); //5 返回 aCell return aCell ;
}
|
1.2 常用操作
1.2.1 单元格的增加/ 删除/ 移动
增加/删除 步骤: 1> 调用单元格编辑判断方法, 指定可被编辑的单元格; 2> 调用单元格编辑样式方法, 指定单元格可被编辑的样式(插入/选中/删除/无); 3>增加调用编辑完成后的方法,判断当前编辑操作并对数据进行相对应的操作
移动 步骤:
1>
设置对应行是否允许移动
; 2>
完成移动后对数据源重新排序;
实例:
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the specified item to be editable.
#warning 编辑 2 该协议方法是询问代理对象对应行是否允许被进行编辑操作 , ( 通过重写该协议方法可以让表视图支持编辑状态 , 默认为全部允许 ) if (indexPath.row == 2) { return NO; } return YES; } #warning 编辑 1 设置编辑样式 - (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath { // 为表视图的对应行指定编辑样式 , 样式有 : 插入 , 删除 , 选中 , 和无 ; if (indexPath.row == self.datasource.count - 1) { return UITableViewCellEditingStyleInsert; } return UITableViewCellEditingStyleDelete; // 删除样式 // return UITableViewCellEditingStyleDelete | UITableViewCellEditingStyleInsert; // 选择样式 } // Override to support editing the table view. - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { #warning 编辑 3 在完成编辑的协议方法中 , 无论是删除样式还是插入样式 , 都需要先操作数据源中的数据 , 在通过表视图的相关方法删除对应行或者插入新的行 if (editingStyle == UITableViewCellEditingStyleDelete) { // Delete the row from the data source [self.datasource removeObjectAtIndex:indexPath.row]; [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];// 只有一个样式 } else if (editingStyle == UITableViewCellEditingStyleInsert) { [self.datasource insertObject:@“GMX” atIndex:indexPath.row]; [tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view } } #warning 移动 2 完成移动后对数据源重新排序 // Override to support rearranging the table view. - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath { // 在界面完成移动时 , 通过此协议方法来更新数据源中的元素顺序 //1. 先获取被移动的数据 id object = [self.datasource [fromIndexPath.row] retain]; //2. 将该对象从数组中移除 [self.datasource removeObjectAtIndex:fromIndexPath.row]; //3. 将对象插入到指定下标 [self.datasource insertObject:object atIndex:toIndexPath.row]; //4. 释放所有权 [object release]; } #warning 移动 1 设置对应行是否允许移动 // Override to support conditional rearranging of the table view. - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath { // Return NO if you do not want the item to be re-orderable. if (indexPath.row == 0) { return NO; }
return YES;
|
1.2.2 为单元格的编辑指定一个动画效果
- //插入一个cell到指定的indexPaths位置,指定一个动画效果
- - (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
- //删除indexPaths位置的cell,指定一个动画效果
- - (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
- //刷新indexPaths位置的cell,指定一个动画效果(tableView的局部刷新,一般用于cell的位置不改变,又不想刷新整个tableView时)
- - (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation NS_AVAILABLE_IOS(3_0);
- //移动indexPaths位置的cell,指定一个动画效果
- - (void)moveRowAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath NS_AVAILABLE_IOS(5_0);
1.2.3 使用索引
- - (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
- {
- return _keyArray;
- }
- // 点击右边索引跳转到哪个index位置
- - (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index
- {
- return index;
- }
2.UITableViewCell
UITableViewCell时UITableView的御用类型,提供了多种预设的内容展示模型,这个类实现了对单元格内容,和背景(包括text/ image/ custom views),单元格的选中状态, 单元格的辅助视图,编辑功能 的管理和设置.
UITableViewCell内默认有contentView和accessoryView两个subView, 可以实现轻量级的自定义单元格. 同时可以通过子类化实现更丰富的单元格的自定义, 自定义cell时可以把自定义的控件添加到contentView 也可以直接添加到cell中
2.1 UITableViewCell 的基本属性
基本属性: 这些基本属性提供了单元格内容的现实, 选择状态的设置,一些界面效果的简单自定义. 提供了自定义单元格时的途径 | |
|
cell包含的视图
|
辅助视图
|
@property
(
nonatomic
,
getter
=
isSelected
)
BOOL
selected
- (
void
)
setSelected:
(
BOOL
)
selected
animated:
(
BOOL
)
animated
@property
(
nonatomic
,
getter
=
isHighlighted
)
BOOL
highlighted
- (
void
)
setHighlighted:
(
BOOL
)
highlighted
animated:
(
BOOL
)
animated
cell的选中状态
|
content内容缩进
|
- (
void
)
willTransitionToState:
(
UITableViewCellStateMask
)
state
- (
void
)
didTransitionToState:
(
UITableViewCellStateMask
)
state
状态的转换(正常状态编辑状态)
|
- (Void) prepareForReuse
当单元格允许重用时, 在单元格被重用之前会调用这个方法, 出于性能的考虑你只需要重置他的基本属性, 例如透明度, 编辑状态, 选择状态, 而不需要修改内容, 如果你要重写这个方法, 那么必须调用父类的实现方法.
这个方法的最大用处是在自定义cell时 需要调用将原有内容抹掉
|
3.代理协议注释:
UITableViewDataSource 协议中常用方法
1.设置右边 索引值
- ( NSArray *)sectionIndexTitlesForTableView:( UITableView *)tableView
2. 设置分组标识
- ( NSString *)tableView:( UITableView *)tableView titleForHeaderInSection:(NSInteger )section
3.设置分组个数
- ( NSInteger )numberOfSectionsInTableView:( UITableView*)tableView
4. 设置行数
- ( NSInteger )tableView:( UITableView *)tableView numberOfRowsInSection:(NSInteger )section
5. 创建cell(使用重用机制,如下例)
- ( UITableViewCell *)tableView:( UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath
*)indexPath
6. 设置 tableView 的每一行的编辑状态(YES,可编辑)
- ( BOOL )tableView:( UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath*)indexPath
7.edit 按钮的点击事件 ( 当点击 edit 按钮时触发 )
- ( void )setEditing:( BOOL )editing animated:( BOOL )animated
8. 当提交编辑操作时触发
- ( void )tableView:( UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle )editingStyle forRowAtIndexPath:( NSIndexPath*)indexPath
9. 设置 tableView 每一行是否允许移动(YES,可移动)
- ( BOOL )tableView:( UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
10. 提交移动操作之后触发
- ( void )tableView:( UITableView *)tableView moveRowAtIndexPath:( NSIndexPath*)sourceIndexPath toIndexPath:( NSIndexPath *)destinationIndexPath
UITableViewDelegate协议中常用方法
1. 设置行高
- ( CGFloat )tableView:( UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
2. 选中cell时触发
- ( void )tableView:( UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
3. 设置 tableViewCell 的编辑样式 ( 插入 / 删除 )
- ( UITableViewCellEditingStyle )tableView:( UITableView *)tableView editingStyleForRowAtIndexPath:( NSIndexPath *)indexPath
4. 设置当点击编辑按钮时 上面显示的文字,如显示删除
- ( NSString *)tableView:( UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:( NSIndexPath *)indexPathNS_AVAILABLE_IOS ( 3 _0) { return @" 删除 " ; }
5. 设置 cell 移动的位置
- ( NSIndexPath *)tableView:( UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:( NSIndexPath *)sourceIndexPath toProposedIndexPath:( NSIndexPath *)proposedDestinationIndexPath
|
4.NSINdexPath
tableview的NSIndexPath时NSIndexPath的类目有row 和 items两个属性