效果
效果.gif
說明
- 點(diǎn)擊單個(gè)cell的時(shí)候桐磁,其展開與縮放動(dòng)畫實(shí)現(xiàn)起來是很麻煩的驯用,做過相關(guān)需求的朋友一定知道其中的坑
實(shí)現(xiàn)思路
首先將cell的高度 封裝到對(duì)應(yīng)的模型中,當(dāng)觸發(fā)事件的時(shí)候修改模型的高度值,然后刷新對(duì)應(yīng)的動(dòng)畫即可
下面上代碼,首先是模型
@interface Model : NSObject
@property (nonatomic) CGFloat normalHeight;
@property (nonatomic) CGFloat expendHeight;
@property (nonatomic) BOOL expend;
+ (instancetype)ModelWithNormalHeight:(CGFloat)normalHeight expendHeight:(CGFloat)expendHeight expend:(BOOL)expend;
@end
#import "Model.h"
@implementation Model
+ (instancetype)ModelWithNormalHeight:(CGFloat)normalHeight expendHeight:(CGFloat)expendHeight expend:(BOOL)expend {
Model *model = [[Model alloc] init];
model.normalHeight = normalHeight;
model.expendHeight = expendHeight;
model.expend = expend;
return model;
}
@end
Cell
#import <UIKit/UIKit.h>
#import "Model.h"
@interface InfoCell : UITableViewCell
@property (nonatomic, weak) NSIndexPath *indexPath;
@property (nonatomic, weak) UITableView *tableView;
- (void)loadData:(id)data;
@end
#import "InfoCell.h"
@interface InfoCell ()
@property (nonatomic, strong) UIButton *button;
@property (nonatomic, weak) Model *model;
@property (nonatomic, strong) UIView *lineView;
@property (nonatomic, strong) UILabel *infoLabel;
@end
@implementation InfoCell
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
[self setup];
}
return self;
}
- (void)setup {
self.selectionStyle = UITableViewCellSelectionStyleNone;
self.button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 320, 100)];
[self.button addTarget:self action:@selector(buttonEvent) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:self.button];
self.lineView = [[UIView alloc] initWithFrame:CGRectMake(0, 49.5, 320, 0.5f)];
self.lineView.backgroundColor = [[UIColor redColor] colorWithAlphaComponent:0.5f];
[self addSubview:self.lineView];
self.infoLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 0, 100, 50)];
self.infoLabel.text = @"Demo";
[self addSubview:self.infoLabel];
}
- (void)buttonEvent {
if (self.model.expend == YES) {
self.model.expend = NO;
[self.tableView beginUpdates];
[self.tableView endUpdates];
[self normalStateWithAnimated:YES];
} else {
self.model.expend = YES;
[self.tableView beginUpdates];
[self.tableView endUpdates];
[self expendStateWithAnimated:YES];
}
}
- (void)loadData:(id)data {
self.model = data;
if (self.model.expend == YES) {
self.lineView.frame = CGRectMake(0, 99.5f, 320, 0.5f);
self.infoLabel.frame = CGRectMake(30, 0, 100, 50);
} else {
self.lineView.frame = CGRectMake(0, 49.5, 320, 0.5f);
self.infoLabel.frame = CGRectMake(10, 0, 100, 50);
}
}
- (void)normalStateWithAnimated:(BOOL)animated {
if (animated == YES) {
[UIView animateWithDuration:0.35f animations:^{
self.lineView.frame = CGRectMake(0, 49.5, 320, 0.5f);
self.infoLabel.frame = CGRectMake(10, 0, 100, 50);
}];
} else {
self.lineView.frame = CGRectMake(0, 49.5, 320, 0.5f);
self.infoLabel.frame = CGRectMake(10, 0, 100, 50);
}
}
- (void)expendStateWithAnimated:(BOOL)animated {
if (animated == YES) {
[UIView animateWithDuration:0.35f animations:^{
self.lineView.frame = CGRectMake(0, 99.5f, 320, 0.5f);
self.infoLabel.frame = CGRectMake(30, 0, 100, 50);
}];
} else {
self.lineView.frame = CGRectMake(0, 99.5f, 320, 0.5f);
self.infoLabel.frame = CGRectMake(30, 0, 100, 50);
}
}
@end
控制器
#import "ViewController.h"
#import "InfoCell.h"
#import "Model.h"
#define INFO_CELL @"INFO_CELL"
@interface ViewController () <UITableViewDelegate, UITableViewDataSource>
@property (nonatomic, strong) NSMutableArray *datasArray;
@property (nonatomic, strong) UITableView *tableView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.datasArray = [NSMutableArray array];
[self.datasArray addObject:[Model ModelWithNormalHeight:50.f expendHeight:100.f expend:NO]];
[self.datasArray addObject:[Model ModelWithNormalHeight:50.f expendHeight:100.f expend:YES]];
[self.datasArray addObject:[Model ModelWithNormalHeight:50.f expendHeight:100.f expend:YES]];
[self.datasArray addObject:[Model ModelWithNormalHeight:50.f expendHeight:100.f expend:YES]];
[self.datasArray addObject:[Model ModelWithNormalHeight:50.f expendHeight:100.f expend:YES]];
[self.datasArray addObject:[Model ModelWithNormalHeight:50.f expendHeight:100.f expend:YES]];
self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
self.tableView.delegate = self;
self.tableView.dataSource = self;
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
[self.tableView registerClass:[InfoCell class] forCellReuseIdentifier:INFO_CELL];
[self.view addSubview:self.tableView];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return _datasArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
InfoCell *cell = [tableView dequeueReusableCellWithIdentifier:INFO_CELL];
cell.indexPath = indexPath;
cell.tableView = tableView;
[cell loadData:_datasArray[indexPath.row]];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
Model *model = _datasArray[indexPath.row];
if (model.expend) {
return model.expendHeight;
} else {
return model.normalHeight;
}
}
@end
關(guān)鍵代碼
關(guān)鍵.png
總結(jié): 動(dòng)畫的關(guān)鍵是如下幾句,在觸發(fā)事件的時(shí)候 執(zhí)行對(duì)應(yīng)的動(dòng)畫即可,但前提是你要修改模型的高度,不然也看不到變化的
[self.tableView beginUpdates];
[self.tableView endUpdates];
//像下面這樣,修改模型高度或給動(dòng)畫 都是可以的
[self normalStateWithAnimated:YES];
讓我們來重點(diǎn)關(guān)注這行代碼:[tableView beginUpdates];
文檔中對(duì)這行代碼的解釋為讓TableView產(chǎn)生插入竞端,刪除或重新加載cell
看到這里大家應(yīng)該就恍然大悟了吧抡蛙?原來當(dāng)我們點(diǎn)擊了一個(gè)cell后我們相當(dāng)于重新加載了一遍我們的tableview茴肥,但是卻和[tableView reloadata]是完全不一樣的風(fēng)格肢娘,reloadData這個(gè)方法會(huì)讓tableView整體重新加載芭逝,相當(dāng)于是作用在tableView上塌碌,而beginUpdates只是作用在cell上!