效果图:

简单说下实现思路:

数据传过来之后, 先创建好对应个数的分组头部View, 也就是要在

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section

在这个方法返回的视图...我这里用的UIButton, 然后监听UIButton的点击, 然后重新刷新这一组

根据UIButton的selected状态来判断是否要展开, 如果是展开, 就返回该组对应的行数, 反之就返回0行就可以了

代码部分:

.h文件

  1. #import <UIKit/UIKit.h>
  2.  
  3. @interface RPCategoryListController : UITableViewController
  4.  
  5. // 分组模型数据
  6. @property (nonatomic, strong) NSArray *category;
  7.  
  8. @end

.m文件

  1. #import "RPCategoryListController.h"
  2. #import "RPCategoryModel.h"
  3. #import "RPChildCategoryModel.h"
  4.  
  5. #define RPSectionTitleHeight 35
  6.  
  7. @interface RPCategoryListController ()
  8.  
  9. @property (nonatomic, strong) NSMutableArray *sectionTitleBtns;
  10.  
  11. @end
  12.  
  13. @implementation RPCategoryListController
  14.  
  15. static NSString * const reuseIdentifier_category = @"Category";
  16.  
  17. #pragma mark - 懒加载
  18.  
  19. - (NSMutableArray *)sectionTitleBtns
  20. {
  21. if (!_sectionTitleBtns) {
  22. _sectionTitleBtns = [[NSMutableArray alloc] init];
  23. }
  24. return _sectionTitleBtns;
  25. }
  26.  
  27. #pragma mark - 系统方法
  28.  
  29. - (instancetype)init
  30. {
  31. return [super initWithStyle:UITableViewStyleGrouped];
  32. }
  33.  
  34. - (void)viewDidLoad
  35. {
  36. [super viewDidLoad];
  37.  
  38. [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:reuseIdentifier_category];
  39. }
  40.  
  41. #pragma mark - Table view data source
  42.  
  43. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
  44. {
  45. return self.category.count;
  46. }
  47.  
  48. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
  49. {
  50. UIButton *sectionTitleBtn;
  51.  
  52. // 获取被点击的组标题按钮
  53. for (UIButton *btn in self.sectionTitleBtns) {
  54. if (btn.tag == section) {
  55. sectionTitleBtn = btn;
  56. break;
  57. }
  58. }
  59.  
  60. // 判断是否展开
  61. if (sectionTitleBtn.isSelected) {
  62. RPCategoryModel *categoryModel = self.category[section];
  63. return categoryModel.childs.count;
  64. }
  65. return ;
  66. }
  67.  
  68. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
  69. {
  70. RPChildCategoryModel *childCategoryModel = [self.category[indexPath.section] childs][indexPath.row];
  71.  
  72. UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier_category forIndexPath:indexPath];
  73. cell.textLabel.textColor = RPFontColor;
  74.  
  75. if ([[RPInternationalControl userLanguage] isEqualToString:@"en"]) {
  76. cell.textLabel.text = childCategoryModel.ename;
  77. } else {
  78. cell.textLabel.text = childCategoryModel.name;
  79. }
  80. return cell;
  81. }
  82.  
  83. - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
  84. {
  85. return self.sectionTitleBtns[section];
  86. }
  87.  
  88. - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
  89. {
  90. return RPSectionTitleHeight;
  91. }
  92.  
  93. - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
  94. {
  95. return ;
  96. }
  97.  
  98. #pragma mark - 私有方法
  99.  
  100. - (void)sectionTitleBtnClick:(UIButton *)sectionTitleBtn
  101. {
  102. // 修改组标题按钮的状态
  103. sectionTitleBtn.selected = !sectionTitleBtn.isSelected;
  104.  
  105. // 刷新单独一组
  106. NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:sectionTitleBtn.tag];
  107. [self.tableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationAutomatic];
  108. }
  109.  
  110. - (void)setCategory:(NSArray *)category
  111. {
  112. _category = category;
  113.  
  114. for (int index = ; index < category.count; index++) {
  115.  
  116. // 组标题按钮的标题
  117. NSString *title = self.category[index] name;
  118.  
  119. // 创建组标题按钮
  120. UIButton *sectionTitleBtn = [UIButton buttonWithType:UIButtonTypeCustom];
  121. sectionTitleBtn.frame = CGRectMake(, , RP_SCREEN_WIDTH, RPSectionTitleHeight);
  122. sectionTitleBtn.tag = index;
  123. sectionTitleBtn.titleLabel.font = [UIFont systemFontOfSize:.f];
  124. [sectionTitleBtn setTitle:title forState:UIControlStateNormal];
  125. [sectionTitleBtn setTitleColor:RPFontColor forState:UIControlStateNormal];
  126. [sectionTitleBtn setBackgroundColor:[UIColor whiteColor]];
  127. [sectionTitleBtn addTarget:self action:@selector(sectionTitleBtnClick:) forControlEvents:UIControlEventTouchUpInside];
  128. [self.sectionTitleBtns addObject:sectionTitleBtn];
  129.  
  130. // 组标题按钮底部分隔线
  131. UIView *bottomLine = [[UIView alloc] initWithFrame:CGRectMake(, sectionTitleBtn.height - , sectionTitleBtn.width, )];
  132. bottomLine.backgroundColor = RPNavBarColor;
  133. bottomLine.alpha = 0.2;
  134. [sectionTitleBtn addSubview:bottomLine];
  135. }
  136. }

关键代码:

NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:sectionTitleBtn.tag];
[self.tableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationAutomatic];

UITableView实现分组, 并且点击每个分组后展开的更多相关文章

  1. 微信分组群发45028,微信分组群发has no masssend quota hint

    微信分组群发45028,微信分组群发has no masssend quota hint >>>>>>>>>>>>>> ...

  2. Python中正则匹配使用findall,捕获分组(xxx)和非捕获分组(?:xxx)的差异

    转自:https://blog.csdn.net/qq_42739440/article/details/81117919 下面是我在用findall匹配字符串时遇到的一个坑,分享出来供大家跳坑. 例 ...

  3. Jquery插件实现点击获取验证码后60秒内禁止重新获取

    通过jquery.cookie.js插件可以快速实现“点击获取验证码后60秒内禁止重新获取(防刷新)”的功能 先到官网(http://plugins.jquery.com/cookie/ )下载coo ...

  4. VS2010 使用时选择代码或双击时出错,点击窗口按钮后VS自动重启问题

    VS2010 使用时选择代码或双击时出错崩溃,点击窗口按钮后VS自动重启问题 下载补丁,打上补丁之后,重启电脑,解决了问题. WindowsXP的下载地址:Windows XP 更新程序 (KB971 ...

  5. android开发之Intent.setFlags()_让Android点击通知栏信息后返回正在运行的程序

    android开发之Intent.setFlags()_让Android点击通知栏信息后返回正在运行的程序     在应用里使用了后台服务,并且在通知栏推送了消息,希望点击这个消息回到activity ...

  6. MonkeyRunner 实现自动点击截屏后与本地图库进行对比输出

    先说下本人是菜鸟,通过网上资料学习,终于调通了MonkeyRunner 实现自动点击截屏后与本地图库进行对比输出,以后做静态UI测试就不需要眼睛盯着看图了,这一切交给MonkeyRunner了. 首先 ...

  7. layui表格点击排序按钮后,表格绑定事件失效解决方法

    最近项目使用layui较为频繁,遇到了一个麻烦的问题,网上搜索也没有看到同类型的问题,故此记下来. 需求是点击上图右侧表格中某一个单元格,会触发点击事件如下代码: $("table>t ...

  8. 点击<a>标签后禁止页面跳至顶部

    一.点击<a>标签后禁止页面跳至顶部 1. 使用 href="javascript:void(0);",例如: <a href="javascript: ...

  9. php中点击下载按钮后待下载文件被清空

    在php中设置了文件下载,下载按钮使用表单的方式来提交 <form method="post" class="form-inline" role=&quo ...

随机推荐

  1. 在C#中使用属性控件添加属性窗口

    转自原文 在C#中使用属性控件添加属性窗口 第一步,创建在应用程序中将要展现的字段属性为public公有属性.其中,所有的属性必须有get和set的方法(如果不设置get方法,则要显示的属性不会显示在 ...

  2. poj Organize Your Train part II

    http://poj.org/problem?id=3007 #include<cstdio> #include<algorithm> #include<cstring& ...

  3. 使用MFC开发有十多年了,结合自身的体会,随便说几句(不能样样都依赖别人,C体系的人,绝对不怕人踢馆)

    挺长时间了吧,这个帖子还没沉下去,使用MFC开发有十多年了,结合自身的体会,随便说几句:1.MFC是一个C++的基础类库,封装了绝大多数的API函数,主要是用来创建带UI的应用程序,服务端程序或着不带 ...

  4. OI经典语录

    1.没有dp的日子仿佛饭菜没放盐,没有树巨结垢的日子仿佛口袋没有钱. 2.算法努力,AC随缘. 3.人生就像OI啊真是又WA又T...---J

  5. (转载)偏序集的Dilworth定理学习

    导弹拦截是一个经典问题:求一个序列的最长不上升子序列,以及求能最少划分成几组不上升子序列.第一问是经典动态规划,第二问直接的方法是最小路径覆盖, 但是二分图匹配的复杂度较高,我们可以将其转化成求最长上 ...

  6. POJ 1511 SPFA+邻接表 Invitation Cards

    题目大意: 计算从 1 点 到 其他所有点的 往返距离之和, 因为是 有向图, 所以我们需要将图反存 一次, 然后求两次单源最短路, 结果就出来了. #include <iostream> ...

  7. 调试makefile—subst函数

    操作系统:ubuntu10.04 Makefile里的subst用法是$(subst FROM,TO,TEXT),即将TEXT中的东西从FROM变为TO Makefile中的字符串处理函数格式:    ...

  8. 2014-08-26 解决HttpContext.Current.Session在ashx文件中出现“未将对象引用设置到对象的实例”的问题

    今天是在吾索实习的第35天. 最近在使用HttpContext.Current.Session来获取Session["..."]的值时,常常会弹出错误——“未将对象引用设置到对象的 ...

  9. in, out, ref

    C#中的函数传递方式可以为in.out.ref(引用) in方式的是默认的传递方式,即向函数内部传送值,不作讲解 很多语言都有类似的操作从函数向调用者返回值,这样我们可以通过函数的调用返回多个值,因为 ...

  10. node.js环境配置(angularjs高级程序设计中出现的错误)

    一:npm install connect会出现错误:解决方法 1:$ npm install connect@2.X.X 2:$ npm install serve-static: 建立server ...