TableView实现QQ好友列表效果

时间:2024-11-18 17:54:48

实现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