Last active
June 22, 2017 23:18
-
-
Save bteapot/31192edbc6de7f2ce5d4 to your computer and use it in GitHub Desktop.
UITableView expandable animated rows
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma mark - BTDurableView | |
@interface BTDurableView : UIView | |
@end | |
@implementation BTDurableView | |
// | |
// ----------------------------------------------------------------------------- | |
- (void)setBackgroundColor:(UIColor *)backgroundColor | |
{ | |
} | |
// | |
// ----------------------------------------------------------------------------- | |
- (void)setBackgroundColorAlternative:(UIColor *)backgroundColor | |
{ | |
[super setBackgroundColor:backgroundColor]; | |
} | |
@end | |
#pragma mark - BTTableViewCell | |
@interface BTTableViewCell : UITableViewCell | |
@property (nonatomic, strong) BTDurableView *innerBox; | |
@end | |
@implementation BTTableViewCell | |
// | |
// ----------------------------------------------------------------------------- | |
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier | |
{ | |
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; | |
if (self) { | |
self.innerBox = [[BTDurableView alloc] initWithFrame:CGRectZero]; | |
[self addSubview:self.innerBox]; | |
self.selectedBackgroundView = [[UIView alloc] initWithFrame:CGRectZero]; | |
self.selectedBackgroundView.backgroundColor = [UIColor colorWithHue:0 saturation:0 brightness:0 alpha:0.5]; | |
} | |
return self; | |
} | |
// | |
// ----------------------------------------------------------------------------- | |
- (void)layoutSubviews | |
{ | |
[super layoutSubviews]; | |
self.innerBox.frame = CGRectInset(self.bounds, 10, 10); | |
} | |
@end | |
#pragma mark - BTViewController | |
@interface BTViewController () <UITableViewDataSource, UITableViewDelegate> | |
@property (nonatomic, strong) UITableView *tableView; | |
@property (nonatomic, strong) NSMutableArray *expansion; | |
@end | |
@implementation BTViewController | |
NSString * const kCellID = @"kCellID"; | |
NSUInteger const kSections = 3; | |
// | |
// ----------------------------------------------------------------------------- | |
- (void)viewDidLoad | |
{ | |
[super viewDidLoad]; | |
self.expansion = [NSMutableArray array]; | |
while (self.expansion.count < kSections) { | |
[self.expansion addObject:[NSMutableIndexSet indexSet]]; | |
} | |
self.tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain]; | |
self.tableView.dataSource = self; | |
self.tableView.delegate = self; | |
self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero]; | |
self.tableView.separatorInset = UIEdgeInsetsZero; | |
self.tableView.layoutMargins = UIEdgeInsetsZero; | |
[self.tableView registerClass:[BTTableViewCell class] forCellReuseIdentifier:kCellID]; | |
[self.view addSubview:self.tableView]; | |
} | |
// | |
// ----------------------------------------------------------------------------- | |
- (void)viewWillLayoutSubviews | |
{ | |
self.tableView.frame = self.view.bounds; | |
} | |
// | |
// ----------------------------------------------------------------------------- | |
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView | |
{ | |
return kSections; | |
} | |
// | |
// ----------------------------------------------------------------------------- | |
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section | |
{ | |
switch (section) { | |
case 0: | |
return 3; | |
case 1: | |
return 7; | |
case 2: | |
return 11; | |
default: | |
return 0; | |
}; | |
} | |
// | |
// ----------------------------------------------------------------------------- | |
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath | |
{ | |
NSMutableIndexSet *indexSet = self.expansion[indexPath.section]; | |
return [indexSet containsIndex:indexPath.row] ? 132 : 44; | |
} | |
// | |
// ----------------------------------------------------------------------------- | |
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath | |
{ | |
BTTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellID forIndexPath:indexPath]; | |
cell.separatorInset = UIEdgeInsetsZero; | |
cell.layoutMargins = UIEdgeInsetsZero; | |
[cell.innerBox setBackgroundColorAlternative: | |
[UIColor colorWithHue:((CGFloat)(indexPath.section + 1) / [tableView numberOfSections]) | |
saturation:(1 - (CGFloat)(indexPath.row + 1) / [tableView numberOfRowsInSection:indexPath.section]) | |
brightness:0.8 | |
alpha:0.5]]; | |
return cell; | |
} | |
// | |
// ----------------------------------------------------------------------------- | |
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section | |
{ | |
return 44; | |
} | |
// | |
// ----------------------------------------------------------------------------- | |
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section | |
{ | |
UIView *view = [[UIView alloc] initWithFrame:CGRectZero]; | |
view.backgroundColor = | |
[UIColor colorWithHue:((CGFloat)(section + 1) / [tableView numberOfSections]) | |
saturation:0.5 | |
brightness:0.8 | |
alpha:1]; | |
return view; | |
} | |
// | |
// ----------------------------------------------------------------------------- | |
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath | |
{ | |
NSMutableIndexSet *indexSet = self.expansion[indexPath.section]; | |
if ([indexSet containsIndex:indexPath.row]) { | |
[indexSet removeIndex:indexPath.row]; | |
} else { | |
[indexSet addIndex:indexPath.row]; | |
} | |
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; | |
[tableView beginUpdates]; | |
[cell layoutSubviews]; | |
[tableView endUpdates]; | |
[tableView deselectRowAtIndexPath:indexPath animated:YES]; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment