总结了几种设置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];
}