宽容他人,放过自己。

点击cell中按钮改变cell高度

Posted on By anchoriteFili

101330016456134.png

总结了几种设置UITableView的cell动态高度的方法
tableView改变cell高度测试.zip

#import "ViewController.h"

#pragma mark 颜色转换宏
#define RGBA_COLOR(R, G, B, A) [UIColor colorWithRed:((R)/255.0f) green:((G)/255.0f) blue:((B)/255.0f) alpha:A]
#define RGB_COLOR(R, G, B) [UIColor colorWithRed:((R)/255.0f) green:((G)/255.0f) blue:((B)/255.0f) alpha:1.0f]

@interface ViewController ()

@property (nonatomic,retain) UITableView *tableView;

@end

NSIndexPath *selectedCellIndexPath; //全局创建一个indexPath用来后边的判断
NSIndexPath *oldCellIndexPath; //老的indexPath

@implementation ViewController

/**
 等数据加载完成后再对selectedCellIndexPath进行赋值,并且先调用一次heightForRowAtIndexPath
 方法,使得刚开始就选中第一个cell
 */
- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:NO];
#pragma mark 设置第一行的高度
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
    selectedCellIndexPath =indexPath;
    oldCellIndexPath = indexPath;
    [self tableView:self.tableView heightForRowAtIndexPath:indexPath];
    
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    //背景颜色
    self.view.backgroundColor = RGB_COLOR(248, 248, 248);
    
#pragma mark 创建tableView<UITableViewDataSource,UITableViewDelegate>
    UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) style:UITableViewStylePlain];
    self.tableView = tableView;
    tableView.delegate = self;
    tableView.dataSource = self;
//    设置tableView背景色为透明色
    tableView.backgroundColor = [UIColor clearColor];
//    分割线样式
    tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
    
    [self.view addSubview:tableView];
    
}

#pragma mark 设置每行的高度
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {

    if(selectedCellIndexPath != nil && [selectedCellIndexPath compare:indexPath] == NSOrderedSame) {
#pragma mark 自适应高度,根据内容来定义其高度
        return 100;
    }
    
    //其它cell的高度
    return 40;
}

#pragma mark 设置section的个数
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    return 1;
}

#pragma mark 设置每个section的行数
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
{
    return 20;
}

#pragma mark cellForRow方法
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier = @"cell";
    TestOneTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (cell == nil) {
        cell = [[TestOneTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
    }
//    设置选择时的状态
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
//    设置cell背景色为透明色
    cell.backgroundColor = [UIColor clearColor];
    
#pragma mark 加个多线程,让这个方法只执行一次
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        //当是第一行的时候,直接对label.frame赋值,并且将其加入到cell上,只执行一次
        if (indexPath.row == 0) {
            cell.label.frame = CGRectMake(0, 0, self.view.frame.size.width, 100);
            [cell.contentView addSubview:cell.label];
            
        }
    });
    
#pragma mark 新老cell不同的配置
    __block TestOneTableViewCell *testCell = cell;
    
//    用来适应行高度
    [cell setMyBlock:^(NSInteger index) {
        if (index == 1) {
            //改变现在的cell中的label的frame
            testCell.label.frame =  CGRectMake(0, 0, self.view.frame.size.width, 100);
            //将现在的indexPath赋值给selectedCellIndexPath
            selectedCellIndexPath = indexPath;
#pragma mark 对上一个cell进行处理,当两次点击的cell不是同一个cell的时候,执行此方法
            if (oldCellIndexPath != selectedCellIndexPath) {
                TestOneTableViewCell*cellOne = (TestOneTableViewCell *)[tableView cellForRowAtIndexPath:oldCellIndexPath];
                cellOne.label.frame = CGRectMake(0, 0, 0, 0);
//                方法执行万后将新的indexPath赋值给老的indexPath
                oldCellIndexPath = selectedCellIndexPath;
            }
#pragma mark 方法执行完后刷新tableView刷新tableView
            [tableView reloadData];
        }
    }];
    
    return cell;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end
#import "TestOneTableViewCell.h"

@implementation TestOneTableViewCell

- (void)awakeFromNib {
    // Initialization code
}

-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        
#pragma mark 创建一个button
        UIButton *Button = [UIButton buttonWithType:UIButtonTypeCustom];
        self.button = Button;
        Button.frame = CGRectMake(300, 10, 40, 30);
        Button.backgroundColor = [UIColor orangeColor];
        [Button setTitle:@"点击" forState:UIControlStateNormal];
        [Button setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
        [Button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];
        [self.contentView addSubview:Button];
        
#pragma mark 创建一个label
        self.labelOne = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 260, 20)];
        self.labelOne.text = @"这个效果我做过,用的不是所谓的插入cell。 你点击后,让你点击的那个cell的frame改变,其实就是height改变,其他的cell通过你的遍历,分别向上或向下移动不同的值即可。需要注意的是,展开后只是tableview的样子变了,他每个cell的属性没有变,所以,需要你把当前的tableview设置为不可滑动。再次点击后,还原,再设置可以滑动。";
        self.labelOne.textColor = [UIColor blackColor];
        self.labelOne.backgroundColor = [UIColor orangeColor];
        self.labelOne.font = [UIFont systemFontOfSize:13.0];
        [self.contentView addSubview:self.labelOne];
        
    }
    return self;
}

#pragma mark 按钮点击方法 按钮点击后再进行赋值 每次点击都会调用一次block方法
- (void)buttonClick:sender {
    
    [self.contentView addSubview:self.label];
    self.myBlock(1);
    
}

#pragma mark label懒加载
- (UILabel *)label {
    if (!_label) {
        _label = [[UILabel alloc] init];
        _label.text = @"这个效果我做过,用的不是所谓的插入cell。 你点击后,让你点击的那个cell的frame改变,其实就是height改变,其他的cell通过你的遍历,分别向上或向下移动不同的值即可。需要注意的是,展开后只是tableview的样子变了,他每个cell的属性没有变,所以,需要你把当前的tableview设置为不可滑动。再次点击后,还原,再设置可以滑动。";
        _label.textColor = [UIColor blackColor];
        _label.numberOfLines = 0;
        _label.backgroundColor = [UIColor orangeColor];
        _label.font = [UIFont systemFontOfSize:13.0];
    }
    return _label;
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];

    // Configure the view for the selected state
}

@end

点击cell控制高度的方法

#pragma mark 设置每行的高度
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {

    if(selectedCellIndexPath != nil && [selectedCellIndexPath compare:indexPath] == NSOrderedSame) {
        return 100;
    }
    
    return 64;
    
}

#pragma mark 添加点击cell的方法
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    
    selectedCellIndexPath = indexPath;
    
    // Forces the table view to call heightForRowAtIndexPath
    [tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
    
}

点击按钮实现cell的高度的改变

typedef void(^PushBlock) (NSInteger index); //用于触发事件

@interface TestOneTableViewCell : UITableViewCell

@property (nonatomic,copy) PushBlock myBlock; //创建block

@end

创建按钮,添加按钮点击事件
#pragma mark 按钮点击方法 按钮点击后再进行赋值 每次点击都会调用一次block方法
- (void)buttonClick:sender {
    self.myBlock(1);
}

NSIndexPath *selectedCellIndexPath; //全局创建一个indexPath用来后边的判断

#pragma mark cellForRow方法
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier = @"cell";
    TestOneTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (cell == nil) {
        cell = [[TestOneTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
    }
    //    设置选择时的状态
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    //    设置cell背景色为透明色
//    cell.backgroundColor = [UIColor blackColor];
    
//    用来适应行高度
    [cell setMyBlock:^(NSInteger index) {
        if (index == 1) {
            selectedCellIndexPath = indexPath;
            
            [tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
        }
    }];
    NSLog(@"%ld",(long)indexPath.row);
    
    return cell;
}

#pragma mark viewWillAppear设置默认选中第一行
/**
 等数据加载完成后再对selectedCellIndexPath进行赋值,并且先调用一次heightForRowAtIndexPath
 方法,使得刚开始就选中第一个cell
 */
- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:NO];
    
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
    selectedCellIndexPath =indexPath;
    [self tableView:self.tableView heightForRowAtIndexPath:indexPath];
}