要通过监听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. COS对象存储服务的使用

    ---------------------------------------------------------------------------------------------[版权申明:本 ...

  2. 微信小程序开发入门篇

    本文档将带你一步步创建完成一个微信小程序,并可以在手机上体验该小程序的实际效果. 开发准备工作 获取微信小程序的 AppID 登录 https://mp.weixin.qq.com ,就可以在网站的& ...

  3. 【安卓开发】Android为什么选择binder

    Binder (Android技术内幕): 在上面这些可供选择的方式中,Android使用得最多也最被认可的还是Binder机制. 为什么会选择Binder来作为进程之间的通信机制呢?因为Binder ...

  4. Android 5.0新控件——TextInputLayout

    Android 5.0(M)新控件--TextInputLayout 介绍之前,先直观的看一下效果 TextInputLayout其实是一个容器,他继承自LinearLayout,该容器是作用于Tex ...

  5. [Mysql]由Data truncated for column联想到的sql_mode配置

    系统日志中出现了 ata truncated for column 'agent' at row 1 mysql出现这个问题的原因,无非就是字符集设置 或者是 字段过长导致的. mysql在初始化的时 ...

  6. Android优化之ViewPager的懒加载

    转载本博客请注明出处:点击打开链接    http://blog.csdn.net/qq_32059827/article/details/52487794 出于对用户消耗流量的考虑,有必要对view ...

  7. ubuntu16.04主题美化和软件推荐

    前几天把ubuntu从15.10更新到了16.10,在网上看到有很多直接更新出问题的,正好赶上换SSD,于是采用全新安装,之前用ubuntu的时候装软件最让人头疼了,这回又得头疼一次了!! 索性把他记 ...

  8. Android之EditText imeOptions属性解析

    在我们的手机中,虽然通常输入法软键盘右下角会是回车按键,但我们经常会看到点击不同的编辑框,输入法软键盘右下角会有不同的图标.例如:  点击浏览器网址栏的时候,输入法软键盘右下角会变成"GO& ...

  9. 【ShaderToy】跳动的心❤️

    写在前面 注:如果你还不了解ShaderToy,请看开篇. 作为ShaderToy系列的第一篇,我们先来点简单的.下面是效果: (CSDN目前不能传gif文件了,暂时空缺,可以看下面的原shader效 ...

  10. iterm2 快捷键

    最近开始使用mac,用iterm2的终端,有些快捷键纪录下. 标签 新建标签:command + t 关闭标签:command + w 切换标签:command + 数字 或者 command + 左 ...