您的位置:首页 > 产品设计 > UI/UE

iOS UITableViewCell 展开实现

2016-01-16 15:31 447 查看
最近遇到了好几个项目中需要实现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
就能展开了。 

本人才学疏浅,欢迎广大同僚 批评指正,共同进步
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: