UITableView相关知识点
- //*****UITableView相关知识点*****//
- 1 #import "ViewController.h"
- // step1 要实现UITableViewDataSource协议,因为tableView不存储数据
- @interface ViewController () <UITableViewDataSource, UITableViewDelegate>
- // step0 准备要显示的数据
- @property(nonatomic,strong) NSMutableArray *dataArrM;
- @property(nonatomic,strong) UITableView *myTable;
- // 这个数组保存着每个分组的折叠状态
- @property(nonatomic,strong) NSMutableArray *sectionShowArrM;
- @end
- @implementation ViewController
- - (void)viewDidLoad {
- [super viewDidLoad];
- [self myTable];
- // 设置导航条
- [self setNavigation ];
- }
- -(void)setNavigation{
- UIBarButtonItem *rightItem = [[UIBarButtonItem alloc]initWithTitle:@"Edit" style:UIBarButtonItemStylePlain target:self action:@selector(tableEdit:)];
- self.navigationItem.rightBarButtonItem = rightItem;
- }
- // 点击导航右侧编辑按钮时,让表格可编辑
- -(void)tableEdit:(UIBarButtonItem *) btnItem{
- if (self.myTable.editing == NO ) { // 没有处于编辑状态,导航按钮文字为“Edit”
- // 点击“编辑”文字,让表格处于编辑状态,并把按钮的文字修改为“Done"
- self.myTable.editing = YES;
- btnItem.title = @"Done";
- // 创建一个新删除按钮
- UIBarButtonItem *deleteBtn = [[UIBarButtonItem alloc]initWithTitle:@"Delete" style:UIBarButtonItemStylePlain target:self action:@selector(DeleteAllSeleted )];
- self.navigationItem.rightBarButtonItems = @[btnItem, deleteBtn];
- }else{
- // 编辑状态下,点击”Done"按钮,取消表格的编辑状态,修改导航按钮文字为"Edit"
- self.myTable.editing = NO;
- btnItem.title = @"Edit" ;
- self.navigationItem.rightBarButtonItems = @[btnItem];
- }
- }
- // 删除选中的所有行
- -(void)DeleteAllSeleted{
- // 获取你选中的所有行
- NSArray *selectedIndexPaths = self.myTable.indexPathsForSelectedRows;
- // 删除数据源
- // for (NSIndexPath *indexPath in selectedIndexPaths ) {
- // // 0 1 2 3 4 5 6 7 8
- // // 1 2 3 4 5 6 7 8
- // // 1 3 4 5 6 7 8
- // // 1 3 5 6 7 8
- // // 0 1 2
- // [self.dataArrM[indexPath.section] removeObjectAtIndex:indexPath.row];
- // }
- // 需要注意的是,一起删除数组中多个元素的时候,需要从数组的大索引值依次向小索引值删除
- for (long i = selectedIndexPaths.count - ; i >= ; i-- ) {
- NSIndexPath *indexPath = selectedIndexPaths[i];
- [self.dataArrM[indexPath.section] removeObjectAtIndex:indexPath.row];
- }
- // 在表格中删除单元格
- [self.myTable deleteRowsAtIndexPaths:selectedIndexPaths withRowAnimation:UITableViewRowAnimationAutomatic];
- for (int i = ; i < self.dataArrM.count; i++ ) {
- NSMutableArray *arr = self.dataArrM[i];
- for (int j = ; j < arr.count ; j++ ) {
- NSLog(@"%@", arr[j]);
- }
- }
- }
- #pragma mark - tableView 的懒加载
- // step2 在当前视图中添加tableView
- -(UITableView *)myTable{
- if ( !_myTable) {
- _myTable =[[ UITableView alloc]initWithFrame:self.view.bounds style:UITableViewStyleGrouped];
- // _myTable = [[UITableView alloc]initWithFrame:CGRectMake(0, 64, self.view.bounds.size.width, self.view.bounds.size.height - 64 ) style:UITableViewStyleGrouped];
- [self.view addSubview:_myTable ];
- // step3 指定数据源代理, tableview的数据由当前控制器提供
- _myTable.dataSource = self; //*********千万别忘记**********
- _myTable.delegate = self; //*********千万别忘记**********
- // 设置表格的footerView
- UIView *footerView = [[UIView alloc]initWithFrame:CGRectMake(, , _myTable.frame.size.width, )];
- footerView.backgroundColor = [UIColor redColor];
- _myTable.tableFooterView = footerView;
- // 设置表格允许多选
- _myTable.allowsMultipleSelection = YES;
- _myTable.allowsSelectionDuringEditing = YES;
- _myTable.allowsMultipleSelectionDuringEditing = YES;
- }
- return _myTable;
- }
- #pragma mark - 数组懒加载
- -(NSMutableArray *)dataArrM{
- if ( !_dataArrM ) {
- _dataArrM = [NSMutableArray array];
- for (int i = ; i < ; i++ ) {
- NSMutableArray *sectionArrM = [NSMutableArray array];
- for (int j = ; j < ; j++ ) {
- NSString *str = [NSString stringWithFormat:@"第%d组,第%d行", i ,j ];
- [sectionArrM addObject:str];
- }
- [_dataArrM addObject:sectionArrM];
- }
- }
- return _dataArrM;
- }
- #pragma mark - 分组是否折叠数据的懒加载
- -(NSMutableArray *)sectionShowArrM{
- if (!_sectionShowArrM ) {
- _sectionShowArrM = [NSMutableArray array];
- for (int i = ; i < self.dataArrM.count ; i++ ) {
- [_sectionShowArrM addObject:@NO]; // 默认起始状态为收起
- }
- }
- return _sectionShowArrM;
- }
- // step4 实现UITableViewDataSource协议方法
- #pragma mark - UITableViewDataSource
- // 返回有多少分组
- -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
- return self.dataArrM.count;
- }
- // 指定每个分组有多少行,返回0行表示该分组不显示单元格
- -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
- if ([self.sectionShowArrM[section] boolValue] == YES) {
- // 如果sectionShowArrM数组中保存当前分组的状态是YES,为展开状态,返回数组元素的个数
- return [self.dataArrM[section] count];
- }else{
- return ; // 收起状态
- }
- }
- // 指定要显示的单元格
- -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
- // 注册单元格类,并指定重用标识
- [tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"cellID"];
- // 从tableView中找一个可重用的单元格,如果没有的话,系统会自动创建一个新的单元格
- UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cellID" forIndexPath:indexPath];
- // 指定单元格要显示的内容
- cell.textLabel .text = self.dataArrM[indexPath.section][indexPath.row];
- //返回单元格
- return cell;
- }
- // 每个分组的头标题
- - (nullable NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
- return [NSString stringWithFormat:@"第%ld组的头", section];
- }
- // 每个分组尾部的标题
- - (nullable NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section{
- return [NSString stringWithFormat:@"第%ld组的尾部", section];
- }
- // 指示是否允许编辑,具体的删除和插入操作由其他协议方法实现
- - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{
- return YES;
- }
- // 指示表格中的行是否可以移动
- - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath{
- return YES;
- }
- // 返回组索引的标题
- - (nullable NSArray<NSString *> *)sectionIndexTitlesForTableView:(UITableView *)tableView{
- NSMutableArray *sectionTitles = [NSMutableArray array];
- for (int i = ; i < self.dataArrM.count ; i++ ) {
- [sectionTitles addObject: [NSString stringWithFormat:@"%d组", i ]];
- }
- return sectionTitles;
- }
- //- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index{
- // if (index == 2 ) {
- // return 0;
- // }else {
- // return index;
- // }
- //}
- // 提交单元格的编辑
- - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
- if (editingStyle == UITableViewCellEditingStyleDelete) {
- // 在数据源数组中删除相应的数据
- [self.dataArrM[indexPath.section] removeObjectAtIndex:indexPath.row];
- // 刷新表格
- [self.myTable deleteRowsAtIndexPaths:@[indexPath ] withRowAnimation:UITableViewRowAnimationAutomatic];
- }else if ( editingStyle == UITableViewCellEditingStyleInsert){
- // 在数据源数组中插入数据
- [self. dataArrM[indexPath.section] insertObject:@"新插入的行" atIndex:indexPath.row ];
- // 刷新单元格
- [self.myTable insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
- }
- }
- // 在该方法中一般实现数据源的交换
- - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath{
- // 取出要移动行的内容
- NSString *row = self.dataArrM[sourceIndexPath.section][sourceIndexPath.row];
- // 在数据源中删除要移动的行
- [self.dataArrM[sourceIndexPath.section] removeObjectAtIndex:sourceIndexPath.row];
- // 在目的地插入要移动的行数据
- [self.dataArrM[destinationIndexPath.section] insertObject:row atIndex:destinationIndexPath.row];
- }
- #pragma mark - UITableViewDelegate
- // 将要显示每个分组的footer的时候调用
- - (void)tableView:(UITableView *)tableView willDisplayFooterView:(UIView *)view forSection:(NSInteger)section{
- // if (section < self.dataArrM.count - 1 ) {
- // return;
- // }
- //
- // //获取更多数据
- // NSMutableArray *addRowsArrM = [NSMutableArray array];
- // for (int i = 0 ; i < 10 ; i++ ) {
- // NSString *addRow = [NSString stringWithFormat:@"新添加的第%d行", i ];
- // [addRowsArrM addObject:addRow];
- // }
- // [self.dataArrM addObject:addRowsArrM];
- // //刷新表格
- // NSIndexSet *indexSet = [[NSIndexSet alloc]initWithIndex:section];
- // [self.myTable reloadSections:indexSet withRowAnimation:UITableViewRowAnimationAutomatic];
- }
- // 返回第一行的高度
- - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
- return ;
- }
- // 返回每个分组头部的高度
- - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
- return ;
- }
- // 返回每个分组尾部的高度
- - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{
- return ;
- }
- // 返回每个分组头部视图,如果实现了这个协议,tableView:titileForHeaderInSection协议方法不再起作用
- - (nullable UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
- UIButton *headerBtn = [[UIButton alloc]initWithFrame:CGRectMake(, , tableView.frame.size.width, )];
- [headerBtn setTitle:[NSString stringWithFormat: @"这是第%ld组的头部", section] forState:UIControlStateNormal] ;
- headerBtn.titleLabel.textAlignment = NSTextAlignmentCenter;
- headerBtn.backgroundColor = [UIColor orangeColor];
- // [headerBtn setImage:[UIImage imageNamed:@"icon_back_highlighted"] forState:UIControlStateNormal];
- UIImageView *btnImg = [[UIImageView alloc]initWithFrame:CGRectMake(, , , headerBtn.frame.size.height)];
- btnImg.contentMode = UIViewContentModeScaleAspectFit;
- btnImg.image = [UIImage imageNamed:@"icon_back_highlighted"];
- [headerBtn addSubview:btnImg];
- // 根据当前分组是否折叠来确定图标的旋转
- BOOL isShow = [self.sectionShowArrM[section] boolValue];
- if (isShow == YES) {
- btnImg.transform = CGAffineTransformRotate(btnImg.transform, -M_PI_2);
- }else{
- btnImg.transform = CGAffineTransformIdentity;
- }
- headerBtn.tag = + section;
- // 添加事件
- [headerBtn addTarget:self action:@selector(showSection: ) forControlEvents:UIControlEventTouchUpInside];
- return headerBtn;
- }
- -(void)showSection:(UIButton *)button{
- long sectionIndex = button.tag - ;
- // 先获取当前分组的折叠状态
- BOOL isShow = [self.sectionShowArrM[sectionIndex] boolValue];
- if (isShow == NO ) { // 如果收起状态,点一下后,修改为展开状态
- self.sectionShowArrM[sectionIndex] = @YES;
- }else { // 展开状态
- self.sectionShowArrM[sectionIndex] = @NO;
- }
- // 刷新当前分组
- NSIndexSet *indexSet = [[NSIndexSet alloc] initWithIndex:sectionIndex];
- [self.myTable reloadSections:indexSet withRowAnimation:UITableViewRowAnimationAutomatic];
- // 让分组头部左侧的图标旋转,这块代码放在这儿不合适,表格刷新后,图标会复位
- // 获取当前按钮中的箭头
- // UIImageView *btnImg;
- // for (UIView *subView in button.subviews) {
- // if ([subView isKindOfClass:[UIImageView class]]) {
- // btnImg = (UIImageView *)subView;
- // break;
- // }
- // }
- //
- // btnImg.transform = CGAffineTransformRotate(btnImg.transform , -M_PI_2);
- }
- // 返回每个分组尾部视图
- // - (nullable UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section{
- //
- // }
- // 返回单元格右侧的辅助按钮的类型
- - (UITableViewCellAccessoryType)tableView:(UITableView *)tableView accessoryTypeForRowWithIndexPath:(NSIndexPath *)indexPath {
- return UITableViewCellAccessoryDisclosureIndicator;
- }
- // 当单元格右侧的辅助视图是一个按钮,当点击该按钮时,执行该协议方法
- - (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath{
- NSLog(@"detailButton be tapped");
- }
- // 指示是否允许高亮显示选中的行
- - (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath{
- return YES;
- }
- // 选中某行时执行
- - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
- NSLog(@"selected: %ld, row:%ld", indexPath.section, indexPath.row);
- }
- // 取消选中时执行,这个方法常在表格允许多选时调用执行
- - (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath{
- NSLog(@"Deselected: %ld, row:%ld", indexPath.section, indexPath.row);
- }
- // 返回编辑时,是删除单元格还是插入单元格,要真正的实现删除或者插入操作,必须实现tableView:commitEditingStyle:forRowAtIndexPath:这个协议方法
- - (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{
- return UITableViewCellEditingStyleInsert;
- }
- // 单元格的缩进
- - (NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath{
- if(indexPath.row % == ){
- return ;
- }else{
- return ;
- }
- }
- @end
UITableView相关知识点
UITableView相关知识点的更多相关文章
- Android开发涉及有点概念&相关知识点(待写)
前言,承接之前的 IOS开发涉及有点概念&相关知识点,这次归纳的是Android开发相关,好废话不说了.. 先声明下,Android开发涉及概念比IOS杂很多,可能有很多都题不到的.. 首先由 ...
- IOS开发涉及有点概念&相关知识点
前言,IOS是基于UNIX的,用C/C+/OC直通系统底层,不想android有个jvm. 首先还是系统架构的分层架构 1.核心操作系统层 Core OS,就是内存管理.文件系统.电源管理等 2.核心 ...
- IOS之UI--小实例项目--添加商品和商品名(使用xib文件终结版) + xib相关知识点总结
添加商品和商品名小项目(使用xib文件终结版) 小贴士:博文末尾有项目源码在百度云备份的下载链接. xib相关知识点总结 01-基本使用 一开始使用xib的时候,如果要使用自定义view的代码,就需要 ...
- 学习记录013-NFS相关知识点
一.NFS相关知识点 1.NFS常用的路径/etc/exports NFS服务主配置文件,配置NFS具体共享服务的地点/usr/sbin/exportfs NFS服务的管理命令,exportfs -a ...
- TCP/IP 相关知识点与面试题集
第一部分:TCP/IP相关知识点 对TCP/IP的整体认 链路层知识点 IP层知识点 运输层知识点 应用层知识点 (这些知识点都可以参考:http://www.cnblogs.com/newwy/p/ ...
- Python开发一个csv比较功能相关知识点汇总及demo
Python 2.7 csv.reader(csvfile, dialect='excel', **fmtparams)的一个坑:csvfile被csv.reader生成的iterator,在遍历每二 ...
- Caffe学习系列(二)Caffe代码结构梳理,及相关知识点归纳
前言: 通过检索论文.书籍.博客,继续学习Caffe,千里之行始于足下,继续努力.将自己学到的一些东西记录下来,方便日后的整理. 正文: 1.代码结构梳理 在终端下运行如下命令,可以查看caffe代码 ...
- php正则相关知识点
关于正则,其实简单就是搜索和匹配.php,java,python等都是支持正则的,php正则兼容perl.好多同学觉得正则比较难,比较抽象,其实正则是非常简单的,主要是一个熟悉和反复练习的结果,还有一 ...
- MySQL自增列(AUTO_INCREMENT)相关知识点总结
MySQL的自增列(AUTO_INCREMENT)和其它数据库的自增列对比,有很多特性和不同点(甚至不同存储引擎.不同版本也有一些不同的特性),让人感觉有点稍微复杂.下面我们从一些测试开始,来认识 ...
随机推荐
- 前端构建:Less入了个门
一.前言 说到前端构建怎能缺少CSS预处理器呢!其实CSS的预处理器有很多啦,比较出名的有Scss.Sass.Stylus和Less.(最近还听说出现了Autoprefixer等CSS后处理器,可 ...
- 百度地图API实现地图定位
1.引用JS: <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0& ...
- javascript学习笔记1-document.write
<html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> ...
- webstorage[html5的本地数据处理]
1.webStorage是什么? webStorage是html5中用于本地化存储的一种方式,而在之前呢我们是用cookie的存储方式处理; 2.那它们之间的区别是什么? Ⅰ.cookie存在的问题: ...
- archive for required library...
最近把移动硬盘上的一个Android项目复制到笔记本上面,import后项目文件夹始终有一个红色叹号,console里面提示“archive for required library...”,原来是l ...
- JavaScript的DOM操作。Window.document对象
间隔执行一段代码:window.setlnteval("需要执行的代码",间隔毫秒数) 例 : window.setlnteval("alert("你 ...
- Apache运行python cgi程序
Apache运行python cgi程序 环境 win10 x64 专业版 Apache2.4 python 2.7 Apache安装和配置 Apache服务器的安装请自行搜索.在Apache2.4中 ...
- android自动化之monkeyrunner
一.使用CMD命令打开模拟器 运行monkeyrunner之前必须先运行相应的模拟器或连上设备,不然monkeyrunner无法连接设备. 1.1 用Elipse打开Android模拟器或在CMD中 ...
- Linux下安装DB2_v9.7详细教程
一:平台 1:HP服务器 cpu:Inter (R) Xeon (R) E5606 2.13G 磁盘:本地磁盘外加存储 2:操作系统 RedHet 5.4 64位 内核:2.6.18-194.1.AX ...
- Tab切换类型
Tab切换类型 点击Tab 滑过Tab 延迟Tab CSS样式 ; ; list-style:none; font-size:12px;} .notice{width:298px; height:98 ...