实现效果如图所示,点击好友分组展开分组下的所有好友。再次点击收回分组。当一个分组处于展开状态时点击其他分组,展开点击的分组并同时收回之前已经展开的分组。
该效果的难点在于:
1.分组的展开与回收
2.点击不同分组时回收之前的分组
分组的显示通过tableView的header实现。每个分组下对应的好友通过tableViewCell实现。
我们通过自定义tableView的header来实现分组效果。自定义header代码如下
在自定义header中我们通过button的点击来实现好友列表的展开与关闭。
因为button我们在view中创建所以我们通过代理将button的点击事件代理到controller中。
注意在此的GroupMode类属性。
该属性的目的是便于我们使用属性的setter方法赋值,也是为了后面用KVO监听属性值的变化而存在的。
自定义header实现文件
这里写了一个类方法。我们用重用的方式创建header.
这里我们用系统自带的layoutSubviews方法来设置空间的frame.当然我们也可以在创建控件的过程中直接设置frame.
使用属性的setter方法赋值,并设置观察者观察GroupModel属性的isOpen属性。
注意这里KVO观察的isOpen属性的目的就是为了标记当前分组的打开关闭状态。
roate方法的作用是旋转分组最左边的三角图片。
在button的点击事件中通过自省让代理执行方法。
这里需要注意的是,在该方法也就是分组被点击的过程中需要不断地改变分组的状态属性的值进而让我们一会在controller中通过该属性值刷新界面。
这里isOpen属性的目的是为了标记分组的打开或者关闭状态。
注意这里的friends这个数组属性,我们来看一下数据结构
Plist数据文件结构
通过数据我们可以看出每个分组里都一个数组,该数组里是分组下每个好友的数据信息,所以这里friends数组属性的目的就是为了储存每个分组下的好友model的。实现代码如下
分组对应的GroupModel的实现文件
在给分组model赋值的过程中获取并封装好友model。
下面我们来看Controller里的实现。
ListTableViewController的实现文件
dataArray属性用来储存分组的model类。
注意在此的GroupModel类属性,该属性的目的是为了接收上一次已经展开的分组对应的model类。
是为了用户点击了不同的分组而之前的分组已经展开时回收之前的分组而存在的。
因为我们当点击了不同的分组时不能确定之前我们点击并已经展开的是哪个分组,所以用该属性储存上一次对应的分组。
方便我们之后刷新界面。原理与点击空白回收键盘的原理是类似的。
在返回每个分区有几行cell时,因为每个分区的cell个数是要根据是否点击分组而展开的。
所以通过isOpen属性来判断该分组是否已经展开返回对应的cell行数。
这是代码的核心,重中之重。
在button的代理方法里,首先判断当前点击的是否是之前展开的分组,如果不是,将之前的分组的model的isOpen设置成NO.刷新界面。
这样在刷新界面的过程中因为isOpen属性为NO,所以该分组下的cell个数为零。效果为回收效果。
,