一、 使用代理模式,需要两个协议.............................................................................................................................................. 1
二、 初始化数据时的一些技巧.......................................................................................................................................................... 2
三、 显示索引条.............................................................................................................................................................................................. 3
四、 UITableViewCell................................................................................................................................................................................. 4
五、 自定义Cell............................................................................................................................................................................................... 5
六、 在tableView中使用alert时.................................................................................................................................................. 7
七、 全部刷新与局部刷新...................................................................................................................................................................... 8
八、 滑动删除功能........................................................................................................................................................................................ 9
九、 性能优化................................................................................................................................................................................................ 12
十、 多行删除................................................................................................................................................................................................ 13
十一、 自定义代理.................................................................................................................................................................................... 18
十二、 手动托动排序功能.................................................................................................................................................................. 19
十三、 取消cell 被点击后的背景色......................................................................................................................................... 20
十四、 cell分隔符的显示.................................................................................................................................................................... 21
十五、 cell被点击时的颜色.............................................................................................................................................................. 21
十六、 UITableView上面出现空白时...................................................................................................................................... 21
一、 使用代理模式,需要两个协议
(1)UITableViewDataSource协议,用于加载资源
required方法
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section——用于返回每个区间的的行数(加载时第二个被调用的)
- (UITableViewCell *)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath——用于返回每一行的cell,在此方法中合成每一行的cell,显示的内容都是在此处被添加进去的,然后将其返回(加载时第二个被调用的)
optional方法
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView——用于返回区间的个数,默认情况下是1,代表只有一个组(加载时第一个被调用的)
(2)UITableViewDelegate协议,给TableView服务的,对TableView的一些动作进行监听
optional方法(所有方法都是)
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
——点击任意一个cell时都会被调用,可以在此方法中实现一些动作
2、在 .h文件中添加完代理后,一定要在 .m 文件中将TableView的dataSource和delegate设置成self;
二、 初始化数据时的一些技巧
(笨方法)
用一个数组来存放所有的数据,数组中的每一项都是一个字典,代表一个区域(组),将这个区域的内容全都存放在这个字典中,组中每一行的内容可以用一个数据来存放
NSArray *array = @[
@{
@"header" : @"头标题",
@"footer" : @"尾标题",
@"array" : @[@"每个区内要显示的内容,用数组存放"]
}
。。。。。。
];
在读取时,先用读数组的方式将一个字典读出,再用读字典的方式将具体内容读出
(常用方法)
将上一个方法中所说的字典抽出一个模型,定义一个类,创建一个个类的对象,再将对象存入数组
Province *zheJiang = [ProvinceprovinceWithHeader:@"浙江"footer:@"浙江商人多" cities:@[@"杭州",@"温州",@"义乌"]];
。。。。
建立多个Province对象再放入数组中
三、 显示索引条
代理中的方法:
-(NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView{
return@[@"A",@"B",@"C",@"D",@"E",@"F"];
}
返回一个数组,将索引中要显示的内容放在这个数组中即可,其中的内容是什么无所谓,只关心这个字符在数组中的位置,比如“C”在2位置,当点击“C”时,自动跳到TableView的第2区域(区域号从0开始)
四、 UITableViewCell
(1)cell的显示样式
Default : 不显示detailTextLabel
Value1 : 在右边显示detailTextLabel
Value2 : 不显示图片,显示detailTextLabel
Subtitle : 在底部显示detailTextLabel
(2)cell的属性accessoryType
用来设置最右边的小图标
(3)cell的属性accessoryView
也是用来设置最右边的小图标,可以自己定义一个view放上去
(4)取消cell被点击的背景色
//取消cell被点击的背影色
[self.tableViewdeselectRowAtIndexPath:indexPath animated:YES];
(5)根据indexPath获得tableView中的一个cell
- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath;
五、 自定义Cell
(1)创建自己的Cell
1>创建一个xib文件,和与之相对应的类文件(只能分开创建,而且类文件继承UITableViewCell),在xib文件中删除自带的View,放上一个TableViewCell,并将这个cell的类,设置为自己创建的 与这个xib文件相对应的类,然后自己设计Cell的内容
(2)使用
1>在代理的方法中使用时,首先要注册
2>注册好以后才能使用
出于优化考虑,首先从重用队列中取出可重用的cell(注意重用标识符,它标识一个重用队列),将其作为新的cell进行赋值,如果重用队列中没有可以用的cell,便要自己新创建一个cell
//从重用队列里取单元格
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CustomCellIdentifier];
//如果重用队列里没有单元格,则创建一个单元格
if (cell == nil) {
cell = [[CustomCellalloc] initWithStyle:UITableViewCellStyleDefaultreuseIdentifier:CustomCellIdentifier];
}
3>在得到一个cell后,再将其赋值并返回(不可以在if中直接赋值,否则是不会出来任何东西的)
cell.headImage.image = [UIImageimageNamed:@"1.jpeg"];
cell.titleLabel.text = [NSStringstringWithFormat:@"产品——%d",indexPath.row];
return cell;
4>注意自定义cell的高度,通过UITableViewDelegate的方法设置
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
六、 在tableView中使用alert时
(1)当点击某一个cell时,弹出一个alert,再点击alert的某个按钮时执行对应的操作
1>在UITableViewDelegate的didSelectRowAtIndexPath方法中创建一个alert,并将alert的代理设置为self,当点击alert上的按钮时处理相应的操作
2>实现alert代理中的clickedButtonAtIndex方法,在这个方法中为了能够知道哪一个cell被点击,即row的值,所以在上一个方法中,将alert的tag值赋为indexPath.row
3>alert的alertViewStyle属性可以设置alert的式样,是否有文本框,以及是哪种文本框
4>alert的textFieldAtIndex方法,可以获得alert上的文本框,index从0开始
七、 全部刷新与局部刷新
(1)全部刷新[self.tableViewreloadData],它将重新调用加载数据时的方法将tableView上的内容全部重新加载
(2)局部刷新
1>方法
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
2>这个方法需要一个数组,里面是IndexPath对象,要先创建数组再刷新
//创建局部刷新所用到的IndexPath数组
NSIndexPath *indexPath = [NSIndexPathindexPathForRow:alertView.taginSection:0];
NSArray *path = @[indexPath];
如果使用这个方法时有现成的indexPath参数,直接使用快捷方式创建这个数组
[tableView reloadRowsAtIndexPaths:@[indexPath]withRowAnimation:…..
(3)无论是全部刷新、局部刷新,还是后面的删除指定行号的cell时,都会调用numberOfRowsInSection方法,在执行上面三种操作时如果都需要改变一些按钮的状态的话,可以把那部分代码放在这个方法里面,达到优化代码的目的
八、 滑动删除功能
(1)启动编辑(第一步)
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{
returnYES;
}
(2)处理删除动作(第二步),只要实现下面这个方法就会有滑动删除
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyleforRowAtIndexPath:(NSIndexPath *)indexPath{
if (editingStyle ==UITableViewCellEditingStyleDelete) {
[_shopsremoveObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArrayarrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
}
1> 根据editingStyle判断是哪种操作,这里面设置成删除操作
2> 删除数据源数组中对应的对象
3> 删除tableView中对应的cell,将 要删除的cell的IndexPath存入一个数组作为这个方法的一个参数
4> 在使用deleteRowsAtIndexPaths方法时,一定要将数据源的数据也删掉,保证在删除之后,cell的个数与数据源数组中成员的个数一致,与delete方法对应的有一个insert方法,可以向tableView中添加一个cell
(3)修改删除按钮标题(可选)
-(NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath{
return@"Delete";
}
滑动删除另一种方法
(1)其实只要实现了commitEditingStyle方法就能实现滑动删除,删除时要先删除模型数据,再删除tableView中的cell,下面是简化的代码
//点击Edit按钮时的动作
- (IBAction)edit:(id)sender {
BOOL result = !self.tableView.editing;
[self.tableViewsetEditing:result animated:YES];
if (result) {
self.editBtn.title = @"Done";
}else{
self.editBtn.title = @"Edit";
}
}
#pragma mark 滑动删除
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyleforRowAtIndexPath:(NSIndexPath *)indexPath{
if (editingStyle != UITableViewCellEditingStyleDelete) return;
[personsremoveObjectAtIndex:indexPath.row];
[self.tableViewdeleteRowsAtIndexPaths:@[indexPath]withRowAnimation:UITableViewRowAnimationAutomatic];
}
九、 性能优化
(1)在创建新的cell之前,先去缓存池中查找,看是否有可用的cell,这些cell都是在滑动屏幕时,那些看不到的cell会被自动放入这个缓存池中
//从缓存池中取出可循环利用的cell
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:systemCell];
(2)如果缓存池中没有可用的cell时,就要新创建一个cell
//如果缓存池中没有可用的cell,创建新的cell
if (cell == nil) {
cell = [[UITableViewCellalloc] initWithStyle:UITableViewCellStyleSubtitlereuseIdentifier:systemCell];
}
(3)要实现以上两个方法,必须要给cell起一个唯一的标识符,当从缓存池中取cell时,就是以这个标识符来区别是否是自己所需的cell,有相同标识符的cell属于同一类型的cell,所以要在以上两个方法之前,先定义一个字符串类型的标识符,如
staticNSString *systemCell = @"systemCell";
static 保存这个变量只被创建一次,避免重复创建
(4)只有在得到cell时,再把所需要的数据赋给cell,注意:不能在新创建cell以后就直接赋值(即在if的那个大括号里),那样会导致所有的cell都一样了
十、 多行删除
(1)在viewDidLoad中设置多行选择为YES
//设置多行编辑为YES
self.tableMSG.allowsMultipleSelectionDuringEditing = YES;
如果不设置这个值,点击“Edit”时出现的是这个画面,但是一旦设置了这个值,滑动删除就会失效
只要编辑了滑动删除的代码,就能实现这样的删除,但是在“Done”的方法中不能调用多行删除的方法
(2)在对应的按钮方法中
1>一开始在创建按钮时就将其tag设置为1(也可以是其它整数)
2>点击按钮后,通过判断tag值来确定是否进入编辑状态
3>如果是,则先启动编辑模式,更改按钮的title,再将tag值改为2
5> 再次点击时,则根据tag值执行删除操作,删除完毕关闭编辑状态,恢复按钮原来的状态
#pragmamark 编辑方法
-(void)edit:(UIBarButtonItem *)sender{
NSLog(@"edit");
if (sender.tag == 1) {
//启动编辑
self.tableMSG.editing = YES;
[sender setTitle:@"Done"];
sender.tag = 2;
}
else{
//执行删除
[selfdeleteSelectedRows];
//恢复原来的状态
self.tableMSG.editing = NO;
[sender setTitle:@"Edit"];
sender.tag = 1;
}
}
6> 注意:要在监听cell被点击的代理方法中(didSelectRowAtIndexPath),首先判断是否是编辑状态,如果是直接返回,如果不是则执行相应的操作,这样就可以避免在进行选择多个时,执行了cell对应的操作
7> 注意:必须要在执行完删除操作以后再把编辑状态取消,否则indexPathsForSelectedRows方法是得不到被选中的那些cell的indexPath的数组的
//首先判断是否是在编辑状态下,如果是直接返回
if (tableView.editing) {
return;
}
8> 在进行多行删除时,要分别对数据源数组和tableView进行删除,所以需要两个重要参数,
9> 一个是indexPath的数组,它是在删除tableView时用到,通过tableView的indexPathsForSelectedRows方法得到一个数组,成员是那些被选中的cell的indexPath,调用tableView的方法删除被选中的cell
//获取被选中的行的indexPath,放进一个数组中去
NSArray *selectedRows = [self.tableMSGindexPathsForSelectedRows];
//判断是否为空
if ([selectedRows count] == 0) {
return;
}
//删除tableView中相应的cell
[self.tableMSGdeleteRowsAtIndexPaths:selectedRows withRowAnimation:UITableViewRowAnimationAutomatic];
10> 一个是indexSet,这是一个堆,存入的是被选中的cell的行号,删除数据源数组时用到这个参数,要先删除数组中的数据,再去删除tableView中的cell
//创建一个堆,保存被选中行的行号,用来删除数据源数组中的数据时使用
NSMutableIndexSet *indexForItemsToDelete = [NSMutableIndexSetnew];
for (NSIndexPath *indexPath in selectedRows) {
[indexForItemsToDelete addIndex:indexPath.row];
}
//删除数据源中对应的实例,上面的堆是一个参数
[del.memorandumremoveObjectsAtIndexes:indexForItemsToDelete];
多行删除另一种方法
(1)在类中定义一个数组如deleteShops,用来存放那些被选中的cell所对应的对象
(2)当加载数据时就可以通过containsObject方法判断这个对象是否在deleteShops数组中,如果在就给cell的后面打一个钩
(3)当要删除时,先获得这些对象在数据源数组中的位置,并创建对应的NSIndexPath对象,放入deleteIndex数组中
(4)先删除模型数据(数据源数组中的数据),再清空deleteShops数组,最后删除tableView中的cell
//获得所要删除数据的行号
NSMutableArray *deleteIndex = [NSMutableArrayarray];
for (Shop *s indeleteShops) {
[deleteIndex addObject:
[NSIndexPathindexPathForRow:[shopsindexOfObject:s] inSection:0]];
}
//删除模型数据
[shopsremoveObjectsInArray:deleteShops];
//清空deleteShops
[deleteShopsremoveAllObjects];
//删除表格中的cell
[self.tableViewdeleteRowsAtIndexPaths:deleteIndex withRowAnimation:UITableViewRowAnimationAutomatic];
十一、 自定义代理
(1)一般用于自定义一个视图时,不仅需要创建对应的类文件,还要给它创建一个代理,以便于在别的视图控制器中使用时,可以使得自定义的视图与其它视力进行信息交流
(2)创建好视图(.xib文件)和对应的类文件后,直接在.h文件中声明这个代理协议
(3)然后在下面的类的声明中,加入一个代理属性
@property (assign, nonatomic) id<BWJRefreshViewDelegate> delegate;
其中必须有assign,delegate的类型为id
(4)协议中只是用来声明方法的,所以不用在.m文件中去实现代理中的方法,当哪一个视图控制器使用自定义的视图时,需要使用代理的时候,再去实现这个代理方法,这个时候由于实现方法编写的位置是在当前的视图控制器中,所在可以直接调用当前文件中的所有方法,实现与当前控制器的其它控件的信息交换
十二、 手动托动排序功能
只要实现代理中的moveRowAtIndexPath方法就会黑夜添加排序功能,但数据源中的排序需要自己来实现
#pragma mark - 排序
//只要实现了这个方法,就会默认添加排序功能
-(void)tableView:(UITableView *)tableViewmoveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath{
Person *p = persons[sourceIndexPath.row];
//先删除原来的数据(必须先删除)
[personsremoveObjectAtIndex:sourceIndexPath.row];
//再插入数据到新位置
[personsinsertObject:p atIndex:destinationIndexPath.row];
}
十三、 取消cell 被点击后的背景色
//取消cell 被点击后的背景色
[tableView deselectRowAtIndexPath:indexPath animated:YES];
十四、 cell分隔符的显示
self.dateTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
十五、 cell被点击时的颜色
cell.selectionStyle = UITableViewCellSelectionStyleNone;
十六、 UITableView上面出现空白时
当出现空白时将控制器的一个属性调制为NO即可消除空白
self.automaticallyAdjustsScrollViewInsets = NO;
iOS 7viewcontroller新增属性automaticallyAdjustsScrollViewInsets,即是否根据按所在界面的navigationbar与tabbar的高度,自动调整scrollview的 inset,设置为no,让它不要自动调整就可以了