实现headerView的单击事件
**分析:**该单击事件中主要实现两个功能,第一是实现箭头的旋转,这可以通过setTransform来实现;第二是实现好友列表的折叠和展开,这可以通过改变该section对应的行数然后刷新单元格来实现,但单击事件是在headerView中实现的,它无法直接刷新单元格,因此需要代理。代理方法虽然可以实现tableView的重载,但是它无法知道当前单击的是哪一个headerView,因此我们需要以单击事件的sender为媒介,传递当前headerView所在的section的索引号,可以通过控件的tag来实现这个目的
//LJGroup类的声明
#import <Foundation/>
#import ""
@interface LJGroup : NSObject
@property(nonatomic , strong) NSString * name;
@property(nonatomic , strong) NSArray * friends;
@property(nonatomic , assign) int online;
//用于记录当前列表是否为展开状态
@property(nonatomic , assign , getter=isopen) Boolean open;
-(instancetype)initWithDic:(NSDictionary *)dic;
+(instancetype)groupWithDic:(NSDictionary *)dic;
@end
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
//LJGroupHeaderView的声明
#import <UIKit/>
#import ""
@class LJGroupHeaderView;
//声明LJGroupHeaderView的delegate方法
@protocol LJGroupHeaderViewDelegate <NSObject>
@optional
-(void)groupHeaderViewDidClicked:(LJGroupHeaderView *)groupHeaderView withSection:(NSInteger)section;
@end
@interface LJGroupHeaderView : UITableViewHeaderFooterView
@property(nonatomic , strong) LJGroup * groupHeaderView_model;
//声明delegate属性
@property(nonatomic , weak) id<LJGroupHeaderViewDelegate> delegate;
+(instancetype)groupHeaderViewWith:(UITableView *)tableView;
@end
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
//在.m文件中为控件注册单击事件并实现
-(void)groupHeaderViewClick:(UIButton *)sender
{
//反转当前的Group的展开状态
self.groupHeaderView_model.open = !self.groupHeaderView_model.open;
[UIView animateWithDuration:0.3 animations:^{
//根据当前的展开状态判断应该旋转的角度
CGFloat angle = self.groupHeaderView_model.isopen ? M_PI_2 : 0;
//使控件旋转
[ setTransform:CGAffineTransformMakeRotation(angle)];
}];
//刷新单元格(调用代理方法)
//获取当前headerView的tag
NSInteger tagnumber = [sender superview].tag;
if ([ respondsToSelector:@selector(groupHeaderViewDidClicked: withSection:)]) {
//调用代理方法
[ groupHeaderViewDidClicked:self withSection:tagnumber ];
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
//在controller中实现tableView的代理方法来返回headerView
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
//获取模型信息
LJGroup * group_current = [section];
//创建headerView
LJGroupHeaderView * headerView = [LJGroupHeaderView groupHeaderViewWith:tableView];
//为headerView赋值
headerView.groupHeaderView_model = group_current;
//指定headerView的delegate属性
= self;
//将当前section的索引号传递给headerView的tag
= section;
//返回headerView
return headerView;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
//在controller中实现LJGroupHeaderView的代理方法
-(void)groupHeaderViewDidClicked:(LJGroupHeaderView *)groupHeaderView withSection:(NSInteger)section
{
NSIndexSet * indexsection = [NSIndexSet indexSetWithIndex:section];
//[ reloadData]太过浪费资源,下面的方法可以进行某个Section的reload,节省资源
[ reloadSections:indexsection withRowAnimation:UITableViewRowAnimationAutomatic];
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
问题:小箭头的旋转是动画形式执行的,动画尚未执行完毕的时候,这个section就已经开始执行reload的代码了,所以会看到箭头刚开始旋转就闪一下又恢复了。
解决办法:将箭头旋转的行为放置在layoutSubvies方法中,这个方法在子视图被重新布局时被自动调用,默认什么也不做。
-(void)layoutSubviews
{
[super layoutSubviews];
[UIView animateWithDuration:0.3 animations:^{
//NSLog(@"该动画被执行了");
CGFloat angle = self.groupHeaderView_model.isopen ? M_PI_2 : 0;
[ setTransform:CGAffineTransformMakeRotation(angle)];
}];
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10