UITableView相关
UITableView的style
- Plain
- Grouped
typedef NS_ENUM(NSInteger, UITableViewStyle) {
UITableViewStylePlain, // regular table view
UITableViewStyleGrouped // preferences style table view
};
只能在创建tableView的时候创建
[[UITableView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height - 70) style:UITableViewStylePlain];
UITableViewController设置风格
UITableViewController *setting = [[UITableViewController alloc]initWithStyle:UITableViewStyleGrouped];
设置索引栏的字体颜色和背景颜色
self.tableView.sectionIndexColor = [UIColor whiteColor];
self.tableView.sectionIndexBackgroundColor = [UIColor blueColor];
自定义Cell注册
//定义一个全局的cellIdentifier变量
NSString *cellId = @"cell";
//将这个cellId变量赋值给forCellReuseIdentifier
//假设ZFTableViewCell是自定义Cell
[self.tableView registerClass:[ZFTableViewCell class] forCellReuseIdentifier:cellId];
使用UITableView设置表格内容需要实现UITableViewDataSource协议
@interface ViewController () <UITableViewDataSource>
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.dataSource = self;
@end
实现了UITableViewDataSource必须要实现的方法
//设置表格每一组有多少栏内容
//tableView指当前调用该方法的表格对象
//section表示表格的组号
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
//设置表格每一栏的具体内容
//tableView指当前调用该方法的表格对象
//indexPath表示调用该方法的表格序号,其中indexPath.section表示组号,indexPath.row表示行号
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
关于创建表格Cell(UITableViewCell)的性能优化
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//以下被注释的方法会造成资源重复创建,效率降低
//UITableViewCell *cell = [[UITableViewCell alloc]init];
//以下的方式原理为将离开视野的UITableViewCell自动放入一个缓冲池中,等有新的UITableViewCell需要创建时,先看看缓冲池中是否有存入的UITableViewCell,如果有则判断预置的id,比如"cell"
static NSString* myId = @"cell";//static声明的变量不会在出了函数体后被销毁
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:myId];
if(cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:myId];
}
cell.....
return cell;
}
如果表格有多组数据,还需要实现(如果是单组,可以不实现)
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;
设置表格每组表头的标题(可选实现)
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection;
设置表格每组表尾的标题(可选实现)
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection;
如果要监听UITableView的一些行为以及设置表格的一些具体属性,还需要实现UIScrollViewDelegate协议
@interface ViewController () <UITableViewDataSource,UIScrollViewDelegate>
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.dataSource = self;
self.tableView.delegate = self;
@end
监听表格某一栏选中事件
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
监听表格某一栏被取消选择的事件
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath;
重新定义表格中的view对象
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section;
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section;
设置表格每组表头和表尾的高度
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section;
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section;
设置表内容栏的高度
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
设置表格右侧的索引栏
- (NSArray<NSString *> *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
//返回一个字符串的数组
return [tableDatas valueForKeyPath:@"title"];
}
刷新整个表格数据
[tableView reloadData];
局部刷新表格数据
//插入数据
[self.tableDatas insertObject:newData atIndex:0];
NSArray *indexPaths = @[[NSIndexPath indexPathForRow:0 inSection:0]];
[self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationMiddle];
//效果动画是一个枚举
/**
UITableViewRowAnimationFade,
UITableViewRowAnimationRight, // slide in from right (or out to right)
UITableViewRowAnimationLeft,
UITableViewRowAnimationTop,
UITableViewRowAnimationBottom,
UITableViewRowAnimationNone, // available in iOS 3.0
UITableViewRowAnimationMiddle, // available in iOS 3.2. attempts to keep cell centered in the space it will/did occupy
UITableViewRowAnimationAutomatic = 100
*/
//刷新数据
[self.tableDatas[0] setValue:@"100" forKey:@"money"];
NSArray *indexPaths = @[[NSIndexPath indexPathForRow:0 inSection:0]];
[self.tableView reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationFade];
//删除数据
[self.tableDatas removeObjectAtIndex:0];
NSArray *indexPaths = @[[NSIndexPath indexPathForRow:0 inSection:0]];
[self.tableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationBottom];
创建删除按钮
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
//删除操作
}
更改默认删除按钮的文字
-(NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath {
return @"删除";
}
创建多个左滑动按钮(注意:以下方法会覆盖默认的删除按钮以及删除方法)
- (NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewRowAction *action1 = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:@"关注" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
NSLog(@"感谢关注");
}];
action1.backgroundColor = [UIColor orangeColor];
UITableViewRowAction *action2 = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"删除" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
[self.tableDatas removeObjectAtIndex:indexPath.row];
//[self.tableView reloadData];
[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationBottom];
}];
UITableViewRowAction *action3 = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:@"相似产品" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
NSLog(@"查看相似产品");
}];
action3.backgroundColor = [UIColor blueColor];
return @[action2,action1,action3];
}
进入,退出编辑模式
self.tableView.editing = YES;//YES为进入,NO为退出
[self.tableView setEditing:YES];
[self.tableView setEditing:YES animated:YES];//带动画的
开启批量选择模式
//在viewDidLoad的时候就可以开启,只需调用一次即可
self.tableView.allowsMultipleSelectionDuringEditing = YES;
批量选择后删除
//先用一个临时的可变数组来保存要删的元素,切勿在原数据中操作,否则会引起数组下标错乱
NSMutableArray *selectDatas = [NSMutableArray array];
for(NSIndexPath *indexPath in self.tableView.indexPathsForSelectedRows)
{
[selectDatas addObject:self.tableDatas[indexPath.row]];
}
//删除数据模型中的被选项
[self.tableDatas removeObjectsInArray:selectDatas];
//删除列表中的被选列
[self.tableView deleteRowsAtIndexPaths:self.tableView.indexPathsForSelectedRows withRowAnimation:UITableViewRowAnimationAutomatic];
动态调整cell高度(iOS8后适用)
tableView.rowHeight = UITableViewAutomaticDimension;
tableView.estimatedRowHeight = 200;
如果使用UITableViewController则无需实现UITableViewDataSource和UIScrollViewDelegate协议,因为内部已经封装实现,但协议中必须实现的方法要实现
UITableView reloadData 视图漂移或者闪动解决方法
视图漂移或者闪动原因: 因为iOS 11后系统默认开启Self-Sizing,首先要知道Self-Sizing是个什么东东。官方文档是这样解释的:大概就是说我们不用再自己去计算cell的高度了,只要设置好这两个属性,约束好布局,系统会自动计算好cell的高度。 IOS11以后,Self-Sizing默认开启,包括Headers, footers。如果项目中没使用estimatedRowHeight属性,在IOS11下会有奇奇怪怪的现象,因为IOS11之前,estimatedRowHeight默认为0,Self-Sizing自动打开后,contentSize和contentOffset都可能发生改变。 所以可以通过以下方式禁用:
在tableView初始化的地方加入下面代码
self.tableView.estimatedRowHeight = 0;
self.tableView.estimatedSectionHeaderHeight = 0;
self.tableView.estimatedSectionFooterHeight = 0;
现在在reloadData视图漂移或者闪动就没有了