Skip to content

Instantly share code, notes, and snippets.

@bteapot
Last active June 22, 2017 23:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save bteapot/31192edbc6de7f2ce5d4 to your computer and use it in GitHub Desktop.
Save bteapot/31192edbc6de7f2ce5d4 to your computer and use it in GitHub Desktop.
UITableView expandable animated rows
#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