iOS中UITableView使用总结

一、初始化方法
- (instancetype)initWithFrame:(CGRect)frame style:(UITableViewStyle)style;
这个方法初始化表视图的frame大小并且设置一个风格,UITableViewStyle是一个枚举,如下:

typedef NS_ENUM(NSInteger, UITableViewStyle) {    
UITableViewStylePlain,                  // 标准的表视图风格    
UITableViewStyleGrouped                 // 分组的表视图风格
};```

二、常用属性
获取表视图的风格(只读属性)
`@property(nonatomic, readonly) UITableViewStyle    style;`
 
设置表示图代理和数据源代理(代理方法后面讨论)
`@property (nonatomic, assign)id <UITableViewDataSource> dataSource;`
`@property(nonatomic, assign)id <UITableViewDelegate>   delegate;`
 
设置表示图的行高(默认为44)
`@property(nonatomic)CGFloat rowHeight; `
 
设置分区的头视图高度和尾视图高度(当代理方法没有实现时才有效)
`@property(nonatomic)CGFloat  sectionHeaderHeight;   `
`@property (nonatomic)CGFloat  sectionFooterHeight; `

设置一个行高的估计值(默认为0,表示没有估计,7.0之后可用)
`@property (nonatomic)CGFloat  estimatedRowHeight; `
注意:这个属性官方的解释是如果你的tableView的行高是可变的,那么设计一个估计高度可以加快代码的运行效率。
 
下面这两个属性和上面相似,分别设置分区头视图和尾视图的估计高度(7.0之后可用)
`@property (nonatomic)CGFloat  estimatedSectionHeaderHeight;  `
`@property (nonatomic)CGFloat  estimatedSectionFooterHeight;`
 
设置分割线的位置
`@property (nonatomic)UIEdgeInsets  separatorInset;`
如果细心,你可能会发现系统默认的tableView的分割线左端并没有顶到边沿。通过这个属性,可以手动设置分割线的位置偏移,比如你向让tableView的分割线只显示右半边,可以如下设置:

UITableView *tab=[[UITableView alloc]initWithFrame:self.view.frame style:UITableViewStylePlain];
tab.separatorInset=UIEdgeInsetsMake(0, tab.frame.size.width/2, 0,0);```

设置tableView背景view视图
@property(nonatomic, readwrite, retain) UIView *backgroundView;

三、常用方法详解
重载tableView
- (void)reloadData;

重载索引栏
- (void)reloadSectionIndexTitles;
这个方法常用语新加或者删除了索引类别而无需刷新整个表视图的情况下。

获取分区数
- (NSInteger)numberOfSections;

根据分区获取行数
- (NSInteger)numberOfRowsInSection:(NSInteger)section;

获取分区的大小(包括头视图,所有行和尾视图)
- (CGRect)rectForSection:(NSInteger)section;

根据分区分别获取头视图,尾视图和行的高度
- (CGRect)rectForHeaderInSection:(NSInteger)section;
- (CGRect)rectForFooterInSection:(NSInteger)section;
- (CGRect)rectForRowAtIndexPath:(NSIndexPath *)indexPath;

获取某个点在tableView中的位置信息
- (NSIndexPath *)indexPathForRowAtPoint:(CGPoint)point;

获取某个cell在tableView中的位置信息
- (NSIndexPath *)indexPathForCell:(UITableViewCell *)cell;

根据一个矩形范围返回一个信息数组,数组中是每一行row的位置信息
- (NSArray *)indexPathsForRowsInRect:(CGRect)rect;

通过位置路径获取cell
- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath;

获取所有可见的cell
- (NSArray *)visibleCells;

获取所有可见行的位置信息
- (NSArray *)indexPathsForVisibleRows;

根据分区获取头视图
- (UITableViewHeaderFooterView *)headerViewForSection:(NSInteger)section;

根据分区获取尾视图
- (UITableViewHeaderFooterView *)footerViewForSection:(NSInteger)section;

使表示图定位到某一位置(行)
- (void)scrollToRowAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UITableViewScrollPosition)scrollPosition animated:(BOOL)animated;
注意:indexPah参数是定位的位置,决定于分区和行号。animated参数决定是否有动画。scrollPosition参数决定定位的相对位置,它使一个枚举,如下:

typedef NS_ENUM(NSInteger, UITableViewScrollPosition) {   
 UITableViewScrollPositionNone,//同UITableViewScrollPositionTop   
 UITableViewScrollPositionTop,//定位完成后,将定位的行显示在tableView的顶部        
UITableViewScrollPositionMiddle,//定位完成后,将定位的行显示在tableView的中间      
 UITableViewScrollPositionBottom//定位完成后,将定位的行显示在tableView最下面
};

使表示图定位到选中行
- (void)scrollToNearestSelectedRowAtScrollPosition:(UITableViewScrollPosition)scrollPosition animated:(BOOL)animated;
这个函数与上面的非常相似,只是它是将表示图定位到选中的行。

四、tableView操作刷新块的应用
在介绍动画块之前,我们先看几个函数:
插入分区
- (void)insertSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation;
animation参数是一个枚举,枚举的动画类型如下

typedef NS_ENUM(NSInteger, UITableViewRowAnimation) {    
UITableViewRowAnimationFade,//淡入淡出  
 UITableViewRowAnimationRight,//从右滑入   
 UITableViewRowAnimationLeft,//从左滑入   
 UITableViewRowAnimationTop,//从上滑入    
 UITableViewRowAnimationBottom,//从下滑入   
 UITableViewRowAnimationNone,  //没有动画   
 UITableViewRowAnimationMiddle,           
 UITableViewRowAnimationAutomatic = 100  // 自动选择合适的动画};```

删除分区
`- (void)deleteSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation;`
重载一个分区
`- (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation ;`
移动一个分区
`- (void)moveSection:(NSInteger)section toSection:(NSInteger)newSection;`
插入一些行
`- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;`
删除一些行
`- (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;`
重载一些行
`- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;`
移动某行
`- (void)moveRowAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath;`
了解了上面几个函数,我们来看什么是操作刷新块:
当我们调用的上面的函数时,tableView会立刻调用代理方法进行刷新,如果其中我们所做的操作是删除某行,而然数据源数组我们可能并没有刷新,程序就会崩溃掉,原因是代理返回的信息和我们删除后不符。
IOS为我们提供了下面两个函数解决这个问题:
开始块标志
`- (void)beginUpdates; `
结束快标志
`- (void)endUpdates;` 
我们可以将我们要做的操作全部写在这个块中,那么,只有当程序执行到结束快标志后,才会调用代理刷新方法。代码示例如下:

[tab beginUpdates];
[tab deleteRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:1 inSection:0]] withRowAnimation:UITableViewRowAnimationLeft];
[dataArray removeObjectAtIndex:1];
[tab endUpdates];```
注意:不要在这个块中调用reloadData这个方法,它会使动画失效。

五、tableView的编辑操作
设置是否是编辑状态(编辑状态下的cell左边会出现一个减号,点击右边会划出删除按钮)
@property (nonatomic, getter=isEditing) BOOL editing;
- (void)setEditing:(BOOL)editing animated:(BOOL)animated;

设置cell是否可以被选中(默认为YES)
@property (nonatomic) BOOL allowsSelection;

设置cell编辑模式下是否可以被选中
@property (nonatomic) BOOL allowsSelectionDuringEditing;

设置是否支持多选
@property (nonatomic) BOOL allowsMultipleSelection;

设置编辑模式下是否支持多选
@property (nonatomic) BOOL allowsMultipleSelectionDuringEditing;

六、选中cell的相关操作
获取选中cell的位置信息
- (NSIndexPath *)indexPathForSelectedRow;

获取多选cell的位置信息
- (NSArray *)indexPathsForSelectedRows;

代码手动选中与取消选中某行
- (void)selectRowAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated scrollPosition:(UITableViewScrollPosition)scrollPosition;
- (void)deselectRowAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated;
注意:这两个方法将不会回调代理中的方法。

七、tableView附件的相关方法
设置索引栏最小显示行数
@property (nonatomic) NSInteger sectionIndexMinimumDisplayRowCount;

设置索引栏字体颜色
@property (nonatomic, retain) UIColor *sectionIndexColor;

设置索引栏背景颜色
@property (nonatomic, retain) UIColor *sectionIndexBackgroundColor;

设置索引栏被选中时的颜色
@property (nonatomic, retain) UIColor *sectionIndexTrackingBackgroundColor;

设置分割线的风格
@property (nonatomic) UITableViewCellSeparatorStyle separatorStyle;
这个风格是一个枚举,如下:

typedef NS_ENUM(NSInteger, UITableViewCellSeparatorStyle) {    
UITableViewCellSeparatorStyleNone,//无线    
UITableViewCellSeparatorStyleSingleLine,//有线    
UITableViewCellSeparatorStyleSingleLineEtched  
};```

 
设置分割线颜色
`@property (nonatomic, retain) UIColor           *separatorColor;`

设置分割线毛玻璃效果(IOS8之后可用)
`@property (nonatomic, copy) UIVisualEffect      *separatorEffect;`
注意:这个属性是IOS8之后新的。
 
设置tableView头视图
`@property (nonatomic, retain) UIView *tableHeaderView;  `
 
设置tableView尾视图
`@property (nonatomic, retain) UIView *tableFooterView; `
 
从复用池中取cell
`- (id)dequeueReusableCellWithIdentifier:(NSString *)identifier;`

获取一个已注册的cell
`- (id)dequeueReusableCellWithIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath`

从复用池获取头视图或尾视图
`- (id)dequeueReusableHeaderFooterViewWithIdentifier:(NSString *)identifier;`
 
通过xib文件注册cell
`- (void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier;`

通过OC类注册cell
 `- (void)registerClass:(Class)cellClass forCellReuseIdentifier:(NSString *)identifier `
上面两个方法是IOS6之后的方法。

通过xib文件和OC类获取注册头视图和尾视图
`- (void)registerNib:(UINib *)nib forHeaderFooterViewReuseIdentifier:(NSString *)identifier;`
`- (void)registerClass:(Class)aClass forHeaderFooterViewReuseIdentifier:(NSString *)`

示范栗子:

[_tableView registerClass:[UITableViewHeaderFooterView class] forHeaderFooterViewReuseIdentifier:@"headerView"];
[_tableView registerClass:[UITableViewHeaderFooterView class] forHeaderFooterViewReuseIdentifier:@"footerView"];
[_tableView registerClass:[TDFMemberLevelSysytemCell class] forCellReuseIdentifier:@"TDFMemberLevelSysytemCell"];
[_tableView registerClass:[TDFMemberLevelBgImageCell class] forCellReuseIdentifier:@"TDFMemberLevelBgImageCell"];

iOS UITableView的代理方法
UITableViewDataSource(数据源代理)
1、必须实现的回调方法
返回每个分区的行数
`- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;`
 
返回每一行的cell
`- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;`
 
2、可选实现的方法
返回分区数(默认为1)
`- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView; `
  
返回每个分区头部的标题
`- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section;`

返回每个分区的尾部标题
`- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section;`

设置某行是否可编辑
`- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath;`

设置某行是否可以被移动
`- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath;`

设置索引栏标题数组(实现这个方法,会在tableView右边显示每个分区的索引)
`- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView; `

设置索引栏标题对应的分区
`- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index`
 
tableView接受编辑时调用的方法
`- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath;`
这个方法中的editingStyle参数是一个枚举,代表了cell被编辑的模式,如下:

typedef NS_ENUM(NSInteger, UITableViewCellEditingStyle) {
UITableViewCellEditingStyleNone,//没有编辑操作
UITableViewCellEditingStyleDelete,//删除操作
UITableViewCellEditingStyleInsert//插入操作
};```

tableView的cell被移动时调用的方法
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath;

UITableViewDelegate(tableView代理)

cell将要显示时调用的方法
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath;

头视图将要显示时调用的方法
- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section;

尾视图将要显示时调用的方法
- (void)tableView:(UITableView *)tableView willDisplayFooterView:(UIView *)view forSection:(NSInteger)section;

和上面的方法对应,这三个方法分别是cell,头视图,尾视图已经显示时调用的方法
- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath*)indexPath;
- (void)tableView:(UITableView *)tableView didEndDisplayingHeaderView:(UIView *)view forSection:(NSInteger)section;
- (void)tableView:(UITableView *)tableView didEndDisplayingFooterView:(UIView *)view forSection:(NSInteger)section;

设置行高,头视图高度和尾视图高度的方法
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section;
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section;

设置行高,头视图高度和尾视图高度的估计值(对于高度可变的情况下,提高效率)
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath*)indexPath;
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForHeaderInSection:(NSInteger)section;
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForFooterInSection:(NSInteger)section;

设置自定义头视图和尾视图
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section;
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section;

设置cell是否可以高亮
- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath;

cell高亮和取消高亮时分别调用的函数
- (void)tableView:(UITableView *)tableView didHighlightRowAtIndexPath:(NSIndexPath *)indexPath;
- (void)tableView:(UITableView *)tableView didUnhighlightRowAtIndexPath:(NSIndexPath *)indexPath;

当即将选中某行和取消选中某行时调用的函数,返回一直位置,执行选中或者取消选中
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath*)indexPath;
- (NSIndexPath *)tableView:(UITableView *)tableView willDeselectRowAtIndexPath:(NSIndexPath*)indexPath;

已经选中和已经取消选中后调用的函数
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath;

设置tableView被编辑时的状态风格,如果不设置,默认都是删除风格
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath;

自定义删除按钮的标题
- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath;

下面这个方法是IOS8中的新方法,用于自定义创建tableView被编辑时右边的按钮,按钮类型为UITableViewRowAction。
- (NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath*)indexPath ;

设置编辑时背景是否缩进
- (BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath*)indexPath;

将要编辑和结束编辑时调用的方法
- (void)tableView:(UITableView*)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath;
- (void)tableView:(UITableView*)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath;

移动特定的某行
- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath;

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,013评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,205评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,370评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,168评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,153评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,954评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,271评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,916评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,382评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,877评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,989评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,624评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,209评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,199评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,418评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,401评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,700评论 2 345

推荐阅读更多精彩内容