您的位置:首页 > 其它

(二十八)QQ好友列表的展开收缩

2015-02-08 21:51 363 查看
要通过监听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:循环利用有时候会引入困扰(修改的内容被新加入的覆盖)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: