最近遇到了好几个项目中需要实现UITableViewCell 点击按钮之后 展开的 需求。针对这种需求 ,一般我使用下面这种解决方法:自定义cell ,点击按钮之前 ,返回一个高度,点击之后返回另一个高度,这个过程中需要一个计算size 的过程,不说了上代码。
最终实现的效果:
我们的UITableViewCell 分为两部分,一个是固定的部分 在cell 的 上部,另外一个是 需要 根据Cell 点击展开的部分,这一部分 可以在 cell 展开状态下显示,关闭状态下隐藏,我使用Xib 创建的Cell 如下
由于下面 一部分 是需要 隐藏的 ,所以我们在设置他的约束的时候需要注意其高度 的 设置,这里牵扯到了Autolayout,我们可以 给 他的高度设置为 距离 父视图顶部 和底部的距离,这样 在 cell 展开的时候 其高度 会增加,关闭反之。
接下来就是按钮的点击事件,我们可以 使用UITableView 代理 方法 -didSelectedItematIndexpath 或者使用按钮的点击事件,点击事件一般更能满足需求,因为一般cell 的点击事件 需要去执行其他的操作,
//
// RAYTaskCell.m
// hooray
//
// Created by wbxiaowangzi on 15/10/19.
// Copyright © 2015年 RAY. All rights reserved.
//
#import "RAYTaskCell.h"
@implementation RAYTaskCell
- (void)awakeFromNib {
// Initialization code
self.fulfilATask.layer.masksToBounds = YES;
self.fulfilATask.layer.cornerRadius = 5;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (IBAction)fulfilATask:(id)sender {
if (self.fulfilTaskBlock) {
self.fulfilTaskBlock(YES);
}
}
- (IBAction)moreTaskInfo:(id)sender {
if (_opened) {
//已经打开就关闭
[self openCell:NO];
}else{
//打开
[self openCell:YES];
}
if (self.moreInfo) {
self.moreInfo(_opened);
}
}
-(void)openCell:(BOOL)open
{
if (open) {
self.moreInfoBtn.imageView.transform = CGAffineTransformMakeRotation(M_PI * 1);
_buttomView.hidden = NO;
}else{
self.moreInfoBtn.imageView.transform = CGAffineTransformMakeRotation(M_PI * 0);
_buttomView.hidden = YES;
}
_opened = open;
}
-(void)showFulfilBtn{
self.fulfilATask.hidden = NO;
self.fulfilBtnH.constant = 42;
}
- (void)hideFulfilBtn{
self.fulfilATask.hidden = YES;
self.fulfilBtnH.constant = 0;
};
@end
以上是cell 的.m文件,主要做了两件事,点击按钮的时候改变 按钮图标的旋转角度,还有提供一个更改自己 附加view高度约束的 方法, 但是由于UITableViewCell复用机制的存在,导致我们的 cell 在复用的时候会保持一些 cell 的 属性,比如说这个 图标的角度,
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
RAYTaskCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if ([_indexPathArr containsObject:indexPath]) {
[cell openCell:YES];
}else {
[cell openCell:NO];
}
if (cell == nil) {
cell = [[[NSBundle mainBundle]loadNibNamed:@"RAYTaskCell" owner:self options:0]lastObject];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
//config cell with model
RAYUserTaskMO *mo = self.taskInfoArr[indexPath.section];
[self configCell:cell withDictionary:(NSDictionary *)mo.lists[indexPath.row]];
__block UITableView *tempTable = _taskTableView;
__block NSIndexPath *tempIndexPath = indexPath;
cell.moreInfo = ^(BOOL opened){
if (opened) {
[_indexPathArr addObject:tempIndexPath];
}else
{
[_indexPathArr removeObject:tempIndexPath];
}
[tempTable reloadData];
};
return cell;
}
如上,我在VC中创建了一个 数组,在点击事件block回调中,当我点击cell展开按钮的时候记录当前indexPath 下cell 的展开状态,如果展开就放进数组,没有展开从数组中移除(这一点其实若判断数组内是否存在该对象更好,我这里没写),然后再复用的时候跟我们的数组中比较,如果该indexPath存在于数组中,那么我们的cell应该是展开 状态,至于cell 展开状态的设置,我们可以 在cell 中暴露方法给控制器,控制器相应去调用就行了,然后 就是 刷新 tableview ,返回不一样的高度,这时我们的cell 就能展开了。
本人才学疏浅,欢迎广大同僚 批评指正,共同进步