一、初始化方法
1:TableView风格设置。
- (instancetype)initWithFrame:(CGRect)frame style:(UITableViewStyle)style;
这个方法初始化表视图的frame大小并且设置一个风格,UITableViewStyle是一个枚举,如下:
typedefNS_ENUM(NSInteger,UITableViewStyle) {
UITableViewStylePlain,// 标准的表视图风格
UITableViewStyleGrouped// 分组的表视图风格
};
2:完成tableView的创建 (cell重用)
传统方法 or 注册法(推荐)
1:传统方法
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"];
if (!cell) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"UITableViewCell"];
}
return cell;
}
2:注册法:(推荐)
1⃣️先在TableView的属性设置(懒加载)注册(这里注册的是Xib的cell,不用Xib的同理)
[tableView registerNib:[UINib nibWithNibName:@"***" bundle:nil] forCellReuseIdentifier:@"Identifier"];
2⃣️:在方法中通过直接获取注册的cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
*** * cell = [tableView dequeueReusableCellWithIdentifier:@"Identifier" forIndexPath:indexPath];
return cell;
}
二、常用属性
TableView视图风格(枚举,只读属性)
@property(nonatomic,readonly)UITableViewStyle style;
设置表示图代理和数据源代理(如果没有设置委托代理,则代理方法中关于TableView的设置无效,新手常犯错误)
@property(nonatomic,assign)id
dataSource; @property(nonatomic,assign)id
delegate;
设置表示图的行高(默认为44)
注意,当使用代理方法设置高度时候,属性设置高度会无效
@property(nonatomic)CGFloat rowHeight;
区头和区尾的高度
(关于高度设置建议不要用属性设置,可在对应的方法中设置:这里方法就不粘贴了)
@property(nonatomic)CGFloat sectionHeaderHeight;
@property(nonatomic)CGFloat sectionFooterHeight;
设置一个行高的估计值(默认为0,表示没有估计,7.0之后可用),
这个属性官方的解释是:如果你的tableView的行高是可变的,那么设计一个估计高度可以加快代码的运行
@property(nonatomic)CGFloat estimatedRowHeight;
// or
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
// return xx }
解释:面对种类不同的 cell,我们依然可以使用简单的 estimatedRowHeight 属性赋值,只要整体估算值接近就可以,比如大概有一半 cell 高度是 44, 一半 cell 高度是 88, 那就可以估算一个 66,基本符合预期。
参考文档:优化UITableViewCell高度计算的那些事
这里做cell高度的动态自适应推荐第三方库UITableView+FDTemplateLayoutCell
设置分区头视图和尾视图的估计高度和上面类似,不再赘述(7.0之后可用)
@property(nonatomic)CGFloat estimatedSectionHeaderHeight;
@property(nonatomic)CGFloat estimatedSectionFooterHeight;,
设置分割线的位置
@property(nonatomic)UIEdgeInsetsseparatorInset;
如果细心,你可能会发现系统默认的tableView的分割线左端并没有顶到边沿。通过这个属性,可以手动设置分
割线的位置偏移,比如你向让tableView的分割线只显示右半边,可以如下设置:
UITableView* tab = [[UITableViewalloc]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参数
决定定位的相对位置,它使一个枚举,如下:
typedefNS_ENUM(NSInteger,UITableViewScrollPosition) {UITableViewScrollPositionNone,//同UITableViewScrollPositionTopUITableViewScrollPositionTop,//定位完成后,将定位的 显 在tableView的顶部UITableViewScrollPositionMiddle,//定位完成后,将定位的 显 在tableView的中间UITableViewScrollPositionBottom//定位完成后,将定位的 显 在tableView最下
};
使表示图定位到选中行
- (void)scrollToNearestSelectedRowAtScrollPosition:(UITableViewScrollPosition)scrollPosition animated:(BOOL)animated;
这个函数与上面的非常相似,只是它是将表示图定位到选中的行。
四、tableView操作刷新块的应用
注意:刷新数据显示有延迟线程原因
[self performInMainThreadBlock:^{
[self.tableView reloadData];
}];
刷新UITableView:整个表
[self.tableView reloadData]
reloadData是刷新整个UITableView,有时候,我们可能需要局部刷新。比如:只刷新一个cell、只刷新一个section等等。这个时候在调用reloadData方法,虽然用户看不出来,但是有些浪费资源。
刷新局部cell
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath,nil] withRowAnimation:UITableViewRowAnimationFade];
这样就可以很方便的刷新第一个section的第一个cell。虽然看起来代码多了,但是确实比较节省资源。尽量少的刷新,也是UITableView的一种优化。下面是TableView涉及到有关刷新的操作,
刷新局部section
NSIndexSet *indexSet = [[NSIndexSet alloc] initWithIndex:0];进阶学习[self.tableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationFade];
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;
我们可以将我们要做的操作全部写在这个块中,那么,只有当程序执行到结束快标志后,才会调用代理刷新方法。代码示例如下:
[tabView beginUpdates];
[tabView deleteRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:1 inSection:0]]withRowAnimation:UITableViewRowAnimationLeft];[dataArray removeObjectAtIndex:1];
[tableView endUpdates];
注意:不要在这个块中调用reloadData这个方法,它会使动画失效。
参考文档:iOS开发小技巧:刷新UITableView
五、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 allowsSelection DuringEditing;设置是否支持多选
@property(nonatomic)BOOL allowsMultipleSelection;设置编辑模式下是否支持多选
@property(nonatomic)BOOL allowsMultipleSelection DuringEditing;
六、选中cell的相关操作
获取选中cell的位置信息
- (NSIndexPath*)indexPathForSelectedRow;
获取多选cell的位置信息
- (NSArray*)indexPathsForSelectedRows;
代码手动选中与取消选中某行
- (void)selectRowAtIndexPath:(NSIndexPath*)indexPath animated:(BOOL)animated scrollPosition:(UITableViewScrollPosition)scrollPosition;
- (void)deselectRowAtIndexPath:(NSIndexPath*)indexPath animated:(BOOL)animated;
注意:这两个方法将不会回调代理中的方法。
选中的cell和上一次选中的cell(单选表:选中的cell打对勾,上次选中的挂饰消失)
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"你选中的%ld",(long)indexPath.row);
}
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {
if ([self.tableView isEditing]) {
//如果tableView是编辑状态-->此方法调用时机:如果你点击的Row已经是被选中的编辑状态,再次点击时调用。
NSLog(@"你取消的编辑状态行号是%ld",(long)indexPath.row);
}else{
//如果tableView不是编辑状态:-->的到你上次点击选中的Row。
NSLog(@"你上次选中的%ld",(long)indexPath.row);
}
}
七、tableView附件的相关方法
设置索引栏最小显示行数
@property(nonatomic)NSIntegersectionIndexMinimumDisplayRowCount;
设置索引栏字体颜色
@property(nonatomic,retain)UIColor*sectionIndexColor;设置索引栏背景颜色
@property(nonatomic,retain)UIColor*sectionIndexBackgroundColor;设置索引栏被选中时的颜色
@property(nonatomic,retain)UIColor*sectionIndexTrackingBackgroundColor;设置分割线的风格
@property(nonatomic)UITableViewCellSeparatorStyleseparatorStyle;这个风格是一个枚举,如下:
typedefNS_ENUM(NSInteger,UITableViewCellSeparatorStyle) {UITableViewCellSeparatorStyleNone,// 线UITableViewCellSeparatorStyleSingleLine,//有线UITableViewCellSeparatorStyleSingleLineEtched
};
设置分割线颜色
@property(nonatomic,retain)UIColor设置分割线毛玻璃效果(IOS8之后可用)
@property(nonatomic,copy)UIVisualEffect注意:这个属性是IOS8之后新的。
*separatorColor;
*separatorEffect;
设置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(iOS6之后)
- (void)registerNib:(UINib*)nib forCellReuseIdentifier:(NSString*)identifier;通过OC类注册cell
- (void)registerClass:(Class)cellClass forCellReuseIdentifier:(NSString*)identifier
通过xib文件和OC类获取注册头视图和尾视图
- (void)registerNib:(UINib*)nib forHeaderFooterViewReuseIdentifier:(NSString*)identifier;
- (void)registerClass:(Class)aClass forHeaderFooterViewReuseIdentifier:(NSString*)
更多方法参考: UITableView详解 UITableView 总结
学无止境,做个记录
2017-01-05 -SXH