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

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

列表收起来的原理:

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

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

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

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

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

实现点击事件:

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

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

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{

    FriendsGroup *group = self.groups[section];
return group.isExpanded ? group.friends.count : 0;
}

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

设置代理的规范:

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

@protocol HeaderViewDelegate <NSObject>

@optional
- (void)headerViewDidClickNameView:(HeaderView *)headerView; @end

2.添加代理成员变量:

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

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

- (void)nameViewClick{
self.group.expanded = !self.group.expanded; if ([self.delegate respondsToSelector:@selector(headerViewDidClickNameView:)]) {
[self.delegate headerViewDidClickNameView:self];
} }

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

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

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

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

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

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

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

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

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

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

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

- (void)didMoveToSuperview{
if (self.group.isExpanded) {
self.nameView.imageView.transform = CGAffineTransformMakeRotation(M_PI_2);
}else{
self.nameView.imageView.transform = CGAffineTransformMakeRotation(0);
}
}

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. JavaScript 函数定义

    JavaScript 使用关键字 function 定义函数. 函数可以通过声明定义,也可以是一个表达式. 函数声明 在之前的教程中,你已经了解了函数声明的语法 : function function ...

  2. Python pandas.io.data 模块迁移

    这段时间用pandas做数据分析, import pandas.io.data as web 然后得到下面的错误提示 "The pandas.io.data module is moved ...

  3. BDD敏捷开发入门与实战

    BDD敏捷开发入门与实战 1.BDD的来由 2003年,Dan North首先提出了BDD的概念,并在随后开发出了JBehave框架.在Dan North博客上介绍BDD的文章中,说到了BDD的想法是 ...

  4. 利用github webhook 结合openresty自动更新静态博客

    使用hexo在github pages上弄了一个静态博客,后来觉得访问有点慢,于是放到自己vps上. 对于静态博客的部署非常简单,本来就是html,js,css等静态文件,只要nginx上配置下目录就 ...

  5. 自己创建一个android studio在线依赖compile

    我正参加2016CSDN博客之星评选麻烦帮下 奖品我随机送给投票者(写一个随机数抽取) http://blog.csdn.net/vote/candidate.html?username=qfanmi ...

  6. Android 开发环境的搭建(新环境)

    最近想往Android 转型,所以又重新捡起Android学习.看了一下各位大神的文章,说的比较乱,因为版本不一样所以搭建过程也不一样,我在这里说一下最简单快捷的方式.(PS:那时候搭建环境好复杂啊, ...

  7. 一个整数数组,有n个整数,如何找其中m个数的和等于另外n-m个数的和?

    int getSum(int* arr, int len) { int sum = 0; for (int i = 0; i < len; ++i) { sum += arr[i]; } ret ...

  8. 2.cocos2dx 3.2中语法的不同之处,lambada表达式的使用和function和bind函数的使用

    1        打开建好的T32  Cocos2dx-3.2的一个项目 2        设置Cocos显示窗口的位置是在AppDelegate.cpp中: 3  设置自适应窗口大小的代码是在上面的 ...

  9. Android Multimedia框架总结(八)Stagefright框架之AwesomePlayer及数据解析器

    转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼:http://blog.csdn.net/hejjunlin/article/details/52503057 前言:前面一篇分析了medi ...

  10. Request和Response的格式

    Request和Response的格式 Request格式: HTTP请求行  (请求)头  空行  可选的消息体 注:请求行和标题必须以<CR><LF> 作为结尾(也就是,回 ...