(二十八)QQ好友列表的展开收缩
要通过监听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:循环利用有时候会引入困扰(修改的内容被新加入的覆盖)。