第一次写博客,可能有很多不对的地方,欢迎大家批评指正。
最近在搞UITableView,遇到了很多问题,怕以后会忘记,所有决定把UITableView的各种用法和使用中遇到的问题整理一下。其中引用了一些前人的总结。
一、初始化方法
- (instancetype)initWithFrame:(CGRect)frame style:(UITableViewStyle)style;
UITableViewStyle 是一个枚举,一共有以下两个值
UITableViewStylePlain 不分组的表视图风格
UITableViewStyleGrouped 分组的表视图风格
例如:初始化一个名为tableView的不分组表视图代码如下
UITableView *tableView = [[UITableViewalloc]initWithFrame:CGRectMake(0,0,375,667) style:UITableViewStylePlain];
二、常用的属性
1.获取table的风格,该属性只读。
@property (nonatomic, readonly) UITableViewStyle style;
例如:获取tableView的风格
UITableViewStyle tableStyle = tableView.style;
2.设置tableView的代理和数据源代理
@property (nonatomic, assign) id <UITableViewDataSource> dataSource;
@property (nonatomic, assign) id <UITableViewDelegate> delegate;
例如:
//设置数据源代理
tableView.dataSource = self;
//设置代理
tableView.delegate = self;
3.设置tableView的cell的高度(默认值为44)(当代理方法没有实现时才有效)
@property (nonatomic)CGFloat rowHeight;
例如:
tableView.rowHeight = 80;
4.设置分组的头视图的高度和脚视图的高度(当代理方法没有实现时才有效)
@property (nonatomic) CGFloat sectionHeaderHeight;
@property (nonatomic) CGFloat sectionFooterHeight;
例如:
tableView.sectionHeaderHeight = 60;
tableView.sectionFooterHeight = 60;
5.设置一个cell高度的估计值(默认为0,7.0之后可用,当高度为动态时,设置一个估计高可以加快代码的运行效率)
@property (nonatomic) CGFloat estimatedRowHeight;
6.设置组头视图和脚视图的估计高度(7.0后可用)
@property (nonatomic) CGFloat estimatedSectionHeaderHeight;
@property (nonatomic) CGFloat estimatedSectionFooterHeight;
7.关于分割线的设置(1)设置分割线的位置
@property (nonatomic) UIEdgeInsets separatorInset;
例如:
tableView.separatorInset = UIEdgeInsetsMake(0, 80, 0, 10);//上,左,下,右
(2)设置分割线的风格
@property (nonatomic)UITableViewCellSeparatorStyle separatorInset;
风格一共有三种,分别是
UITableViewCellSeparatorStyleSingleLine 有一根线
UITableViewCellSeparatorStyleNone 没有线
UITableViewCellSeparatorStyleSingleLineEtched 有一根线,但是看不见,而且只支持分组分割
例如:tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
(3)设置分割线的颜色
tableView.separatorColor = [UIColor magentaColor];
(4)设置分割线模糊效果(iOS 8.0之后可用)
tableView.separatorEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
/*
UIBlurEffectStyleExtraLight,
较浅
UIBlurEffectStyleLight,
浅
UIBlurEffectStyleDark
深
*/
8.设置tableView背景View视图 @property(nonatomic, readwrite, retain) UIView *backgroundView;
(继承于UIView的视图都可用作为背景视图)
9.设置表格的头视图
tableView.tableHeaderView = headerView;
10,设置表格的脚视图
tableView.tableFooterView = footerView;
(继承与UIView的视图都可用作为表格的头视图和脚视图。注意这里是整个表格的头视图和脚视图,不是分组的头视图脚视图)11.关于索引
(1)设置索引文字的颜色
tableView.sectionIndexColor = [UIColor whiteColor];
(2)设置索引的背景颜色
tableView.sectionIndexBackgroundColor = [UIColor clearColor];
(3)设置拖拽时索引的背景颜色
tableView.sectionIndexTrackingBackgroundColor = [UIColor redColor];
(4)设置当组数超过多少时显示索引tableView.sectionIndexMinimumDisplayRowCount = 10;
12.获取分区数
@property (nonatomic, readonly) NSInteger numberOfSections;
例如: NSInteger *integer = tableView. numberOfSections ;13.获取所有可见的cell
@property (nonatomic, readonly) NSArray<__kindof UITableViewCell *> *visibleCells;
14.获取所有可见cell的位置信息@property (nonatomic, readonly, nullable) NSArray<NSIndexPath *> *indexPathsForVisibleRows;
15.设置是否是编辑状态(编辑状态时cell的左边会出现一个减号或加号按钮,点击cell会左滑出添加或删除)
@property (nonatomic, getter=isEditing) BOOL editing;
- (void)setEditing:(BOOL)editing animated:(BOOL)animated;
16.设置cell是否可以被选中(默认可以)@property (nonatomic) BOOL allowsSelection;
17.设置cell编辑模式下是否可以被选中
@property (nonatomic) BOOL allowsSelectionDuringEditing;
18.设置是否支持多选
@property (nonatomic) BOOL allowsMultipleSelection;
19.设置编辑模式下是否支持多选
@property (nonatomic) BOOL allowsMultipleSelectionDuringEditing;
20,获取选中cell的位置信息@property (nonatomic,readonly,nullable)NSIndexPath *indexPathForSelectedRow;
21.获取多选cell的位置信息@property (nonatomic,readonly,nullable)NSArray<NSIndexPath *> *indexPathsForSelectedRows
三、常用的方法
1.重载tableView
- (void)reloadData;
例如:
[tableView reloadData];
2.重载搜索引栏- (void)reloadSectionIndexTitles;
例如:
[tableView reloadSectionIndexTitles];
3.根据分区获取该分区行数
- (NSInteger)numberOfRowsInSection:(NSInteger)section;
例如:
[tableView numberOfRowsInSection:0];
4.根据分区获取分区大小(包括头视图、所有行和尾视图)
- (CGRect)rectForSection:(NSInteger)section;
- (CGRect)rectForHeaderInSection:(NSInteger)section;
- (CGRect)rectForFooterInSection:(NSInteger)section;
- (CGRect)rectForRowAtIndexPath:(NSIndexPath *)indexPath;
(以上这几个方法中的头、尾视图只组的头视图和尾视图)5.获取某个点在tableView中的位置信息
- (NSIndexPath *)indexPathForRowAtPoint:(CGPoint)point;
6.获取某个cell在tableView中的位置信息
- (NSIndexPath *)indexPathForCell:(UITableViewCell *)cell;
7.根据一个矩形范围返回一个信息数组,数组中存的是每一行的位置信息
- (NSArray *)indexPathsForRowsInRect:(CGRect)rect;
8.通过index获取cell
- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath;
9.根据分区获取组头视图
- (UITableViewHeaderFooterView *)headerViewForSection:(NSInteger)section;
根据分区获取组脚视图
- (UITableViewHeaderFooterView *)footerViewForSection:(NSInteger)section;
10,让tableView滚动到某一行
- (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最下面
};
11.使tableView滚动到选中行
- (void)scrollToNearestSelectedRowAtScrollPosition:(UITableViewScrollPosition)scrollPosition animated:(BOOL)animated;
12.插入一个组
- (void)insertSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation;
animation参数是一个枚举,枚举的动画类型如下
typedef NS_ENUM(NSInteger, UITableViewRowAnimation) {
UITableViewRowAnimationFade,//淡入淡出
UITableViewRowAnimationRight,//从右滑入
UITableViewRowAnimationLeft,//从左滑入
UITableViewRowAnimationTop,//从上滑入
UITableViewRowAnimationBottom,//从下滑入
UITableViewRowAnimationNone, //没有动画
UITableViewRowAnimationMiddle,
UITableViewRowAnimationAutomatic = 100 // 自动选择合适的动画
};
13。删除一个组
- (void)deleteSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation;
14.重载一个组
- (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation ;
15.移动一个组
- (void)moveSection:(NSInteger)section toSection:(NSInteger)newSection;
16.插入一些行
- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
17.删除一些行
- (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
18.重载一些行
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
19.移动某行
- (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这个方法,它会使动画失效。
20.代码手动选中与取消选中某行
- (void)selectRowAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated scrollPosition:(UITableViewScrollPosition)scrollPosition;
- (void)deselectRowAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated;
注意:这两个方法将不会回调代理中的方法。
21.从复用池中取cell- (id)dequeueReusableCellWithIdentifier:(NSString *)identifier;
22.获取一个已注册的cell
- (id)dequeueReusableCellWithIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath*)indexPath
23.从复用池获取头视图或尾视图
- (id)dequeueReusableHeaderFooterViewWithIdentifier:(NSString *)identifier;
24.通过xib文件注册cell
- (void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier;
25.通过OC类注册cell
- (void)registerClass:(Class)cellClass forCellReuseIdentifier:(NSString *)identifier
26. 通过xib文件和OC类获取注册头视图和尾视图
- (void)registerNib:(UINib *)nib forHeaderFooterViewReuseIdentifier:(NSString*)identifier;
- (void)registerClass:(Class)aClass forHeaderFooterViewReuseIdentifier:(NSString *)