要通过监听HeaderView上面的Button来进行操作:

通过addTarget方法即可,应该将按钮的点击方法封装在HearView控制器内部。

列表收起来的原理:

tableView: numberOfRowsInSection: 方法返回0就是不显示,注意要刷新表格。

只要在Group模型中定义一个变量表示是否展开:

  1. /**
  2. * 是否需要展开
  3. */
  4. @property (nonatomic, assign, getter = isExpanded) BOOL expanded;

然后利用addTarget方法给按钮添加事件:

  1. [nameView addTarget:self action:@selector(nameViewClick) forControlEvents:UIControlEventTouchUpInside];

实现点击事件:

  1. - (void)nameViewClick{
  2. self.group.expanded = !self.group.expanded;
  3. }

在控制器内部进行判断和返回:

  1. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
  2.  
  3. FriendsGroup *group = self.groups[section];
  4. return group.isExpanded ? group.friends.count : 0;
  5. }

需要注意的是只有数据刷新的时候才会调用上面的方法,因此在点击按钮时还应该调用tableView的reloadData方法,但是点击事件在HeaderView的控制器里,因此应该tableView控制器监听按钮点击,即称为HeaderView的代理。

设置代理的规范:

1.声明协议:注意协议名以类名开头,方法名也以类名开头,建议写@option,如果写了@option,一定要在调用代理方法时检查有没有这个方法(respondsTo...方法)。

  1. @protocol HeaderViewDelegate <NSObject>
  2.  
  3. @optional
  4. - (void)headerViewDidClickNameView:(HeaderView *)headerView;
  5.  
  6. @end

2.添加代理成员变量:

  1. @property (nonatomic, weak) id<HeaderViewDelegate> delegate;

3.更新上面的按钮点击事件,调用代理方法,注意的是检查这个方法有没有被代理实现:一定要用respondsTo...方法检查。

  1. - (void)nameViewClick{
  2. self.group.expanded = !self.group.expanded;
  3.  
  4. if ([self.delegate respondsToSelector:@selector(headerViewDidClickNameView:)]) {
  5. [self.delegate headerViewDidClickNameView:self];
  6. }
  7.  
  8. }

4.tableView控制器遵循protocol(在interface处遵循)。

5.在新建HeaderView时将delegate设定为自身(self)。

6.实现这个方法,刷新数据:

  1. - (void)headerViewDidClickNameView:(HeaderView *)headerView{
  2. [self.tableView reloadData];
  3. }

一个细节:在按钮展开的时候,需要把前面的箭头由向右变为向下,一个直接的思路是在HeaderView的Click方法内进行旋转:

  1. </pre>注意transfrom属性设置以CGAffine开头,旋转式弧度<pre name="code" class="objc"> if (self.group.isExpanded) {
  2. self.nameView.imageView.transform = CGAffineTransformMakeRotation(M_PI_2);
  3. }else{
  4. self.nameView.imageView.transform = CGAffineTransformMakeRotation(0);
  5. }

旋转的细节:imageView的旋转是将内容旋转,默认拉伸,如果要让箭头不失真,应该让内容居中不拉伸,为了防止图片显示不全,应该关掉clipToBounds方法:

  1. nameView.imageView.contentMode = UIViewContentModeCenter;
  2. nameView.imageView.clipsToBounds = NO;

这样是无效的,因为在这之后调用了reloadData方法,调用这个方法后加载的HeaderView并不是从缓存池中取得的而是新建的。

因此应该监听新HeaderView的添加,使用didMoveToSuperview方法或者willMoveToSuperview:(传入要添加的控件)。

只需要将上面的内容在HeaderView的didMoveToSuperview中实现即可。

  1. - (void)didMoveToSuperview{
  2. if (self.group.isExpanded) {
  3. self.nameView.imageView.transform = CGAffineTransformMakeRotation(M_PI_2);
  4. }else{
  5. self.nameView.imageView.transform = CGAffineTransformMakeRotation(0);
  6. }
  7. }

Tip:循环利用有时候会引入困扰(修改的内容被新加入的覆盖)。

(二十八)QQ好友列表的展开收缩的更多相关文章

  1. (二十七)QQ好友列表的实现

    QQ好友列表通过plist读取,plist的结构为一组字典,每个字典内有本组的信息和另外一组字典代表好友. 要读取plist,选择合适的数据结构,例如NSArray,然后调用initWithConte ...

  2. Bootstrap <基础二十八>列表组

    列表组.列表组件用于以列表形式呈现复杂的和自定义的内容.创建一个基本的列表组的步骤如下: 向元素 <ul> 添加 class .list-group. 向 <li> 添加 cl ...

  3. JAVA之旅(二十八)——File概述,创建,删除,判断文件存在,创建文件夹,判断是否为文件/文件夹,获取信息,文件列表,文件过滤

    JAVA之旅(二十八)--File概述,创建,删除,判断文件存在,创建文件夹,判断是否为文件/文件夹,获取信息,文件列表,文件过滤 我们可以继续了,今天说下File 一.File概述 文件的操作是非常 ...

  4. iOS开发UI篇—使用UItableview完成一个简单的QQ好友列表(一)

    iOS开发UI篇—使用UItableview完成一个简单的QQ好友列表(一) 一.项目结构和plist文件 二.实现代码 1.说明: 主控制器直接继承UITableViewController // ...

  5. Citrix 服务器虚拟化之二十八 XenApp6.5发布文档内容

    Citrix 服务器虚拟化之二十八  XenApp 6.5发布文档内容 XenApp可发布以下类型的资源向用户提供信息访问,这些资源可在服务器或桌面上虚拟化: 1)  服务器桌面:发布场中服务器的整个 ...

  6. VMware vSphere 服务器虚拟化之二十八 桌面虚拟化之安装View传输服务器

    VMware vSphere 服务器虚拟化之二十八 桌面虚拟化之安装View传输服务器 View 传输服务器用于管理和简化数据中心与在最终用户本地系统上检出使用的 View 桌面之间的数据传输.必须安 ...

  7. android 实现QQ好友列表

    在某些Android开发群里,看到有些新手问怎么实现QQ好友列表,其实网上一搜挺多的.接触Android,也才一年的时间,大部分时间花在工作上(解bug...),界面上开发很少参与.自己维护的系统应用 ...

  8. (转载)Android项目实战(二十八):使用Zxing实现二维码及优化实例

    Android项目实战(二十八):使用Zxing实现二维码及优化实例 作者:听着music睡 字体:[增加 减小] 类型:转载 时间:2016-11-21我要评论 这篇文章主要介绍了Android项目 ...

  9. swift 实现QQ好友列表功能

    最近项目中有类似QQ好友列表功能,整理了一下,话不多说,直接上代码 import UIKit class QQFriend: NSObject { var name: String? var intr ...

随机推荐

  1. freemarker的使用

    一:freemarker是什么? freemarker是一个模板引擎,基于定义的模板和数据生成对应的文本(HTML,xml,java等),是一个生成文本的工具. 二:freemarker的使用方法 ( ...

  2. MySQL系列教程(五)

    MyCAT MyCat是基于阿里开源的Cobar产品而研发,Cobar的稳定性.可靠性.优秀的架构和性能以及众多成熟的使用案例使得MYCAT一开始就拥有一个很好的起点,站在巨人的肩膀上,我们能看到更远 ...

  3. Android简易实战教程--第五十一话《使用Handler实现增加、减少、暂停计数》

    转载博客请注明出处:道龙的博客 之前,写过一篇使用异步任务AysncTask实现倒计时的小案例,喜欢的话可以参考博客:Android简易实战教程--第三十三话< AsyncTask异步倒计时&g ...

  4. AsyncTask还要知道的一些知识

    在之前的博客中,对AsyncTask做过详细分析,而且也以小案例的形式,介绍如何基本的使用它.今天再来探讨它,更多的认识,尤其在面试中以下面方式回答,可能印象分更多一些. 面试题:讲一讲您对Async ...

  5. React Native之ListView实现九宫格效果

    概述 在安卓原生开发中,ListView是很常用的一个列表控件,那么React Native(RN)如何实现该功能呢?我们来看一下ListView的源码 ListView是基于ScrollView扩展 ...

  6. Android传感器

    Android传感器 开发传感器应用 1. 获取传感器管理者对象 // 获取传感器管理者对象 SensorManager mSensorManager = (SensorManager) getSys ...

  7. 指令汇B新闻客户端开发(六) 浅谈屏幕适配解决方案

    屏幕适配的问题,我相信很多大牛的经验远比我丰富,在此就简单的分享一下我所做的的屏幕适配方案,当然我说的是安卓方面的啦,嘿嘿,屏幕适配我们一般用1280*720的屏幕作为我们的主流开发屏,当然现在And ...

  8. 14 Fragment 碎片总结

    Fragment 碎片 一, Fragment是什么? Android 3.0以后出现的 Api11 以上 Activity的组成部分 Fragment(小的Activity) Fragment可以显 ...

  9. NET中小型企业级项目开发架构系列(一)

    前端时间我们开发了基于Net的一套搭建sprint.NET+NHibernate+MVC+WCF+EasyUI等中小型企业级系统开发平台,现在把整个开发过程中的步步进展整理出来和大家分享,这个系列可能 ...

  10. arm-linux内核编译过程小结

    记在前面的杂七杂八 内核的生成,实际上最终的目的是生成一个binary文件zImage,大小2-5MB的数量级. 用户可以从kernel.org得到的tar.gz格式的内核源代码,此代码解压后,就会生 ...