(二十八)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:循环利用有时候会引入困扰(修改的内容被新加入的覆盖)。



原文地址:https://www.cnblogs.com/aiwz/p/6154225.html