Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions SLExpandableTableView/SLExpandableTableView.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ typedef enum {
- (void)tableView:(SLExpandableTableView *)tableView willCollapseSection:(NSUInteger)section animated:(BOOL)animated;
- (void)tableView:(SLExpandableTableView *)tableView didCollapseSection:(NSUInteger)section animated:(BOOL)animated;

- (BOOL)tableView:(SLExpandableTableView *)tableView shouldAnimateScrollToSection:(NSUInteger)section;

@end


Expand Down
96 changes: 53 additions & 43 deletions SLExpandableTableView/SLExpandableTableView.m
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,10 @@ @implementation SLExpandableTableView
}

- (void)setDelegate:(id<SLExpandableTableViewDelegate>)delegate {
_myDelegate = delegate;
[super setDelegate:self];
if (delegate != nil){
_myDelegate = delegate;
[super setDelegate:self];
}
}

- (id<UITableViewDataSource>)dataSource {
Expand Down Expand Up @@ -89,7 +91,7 @@ - (BOOL)respondsToSelector:(SEL)aSelector
} else if (protocol_containsSelector(@protocol(UITableViewDelegate), aSelector)) {
return [super respondsToSelector:aSelector] || [_myDelegate respondsToSelector:aSelector];
}

return [super respondsToSelector:aSelector];
}

Expand All @@ -100,7 +102,7 @@ - (id)forwardingTargetForSelector:(SEL)aSelector
} else if (protocol_containsSelector(@protocol(UITableViewDelegate), aSelector)) {
return _myDelegate;
}

return [super forwardingTargetForSelector:aSelector];
}

Expand Down Expand Up @@ -132,10 +134,10 @@ - (void)commonInit {
- (void)awakeFromNib
{
[super awakeFromNib];

_storedTableHeaderView = self.tableHeaderView;
_storedTableFooterView = self.tableFooterView;

self.tableHeaderView = self.tableHeaderView;
self.tableFooterView = self.tableFooterView;
}
Expand Down Expand Up @@ -165,7 +167,7 @@ - (void)reloadDataAndResetExpansionStates:(BOOL)resetFlag {
if (resetFlag) {
[self _resetExpansionStates];
}

if (self.onlyDisplayHeaderAndFooterViewIfTableViewIsNotEmpty) {
if ([self numberOfSections] > 0) {
if ([super tableFooterView] != self.storedTableFooterView) {
Expand All @@ -183,7 +185,7 @@ - (void)reloadDataAndResetExpansionStates:(BOOL)resetFlag {
[super setTableHeaderView:self.storedTableHeaderView];
}
}

[super reloadData];
}

Expand All @@ -199,60 +201,65 @@ - (void)expandSection:(NSInteger)section animated:(BOOL)animated {
// section is already showing, return
return;
}

[self deselectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:section] animated:NO];

if ([self.myDataSource tableView:self needsToDownloadDataForExpandableSection:section]) {
// data is still not ready to be displayed, return
[self downloadDataInSection:section];
return;
}

if ([self.myDelegate respondsToSelector:@selector(tableView:willExpandSection:animated:)]) {
[self.myDelegate tableView:self willExpandSection:section animated:animated];
}

self.animatingSectionsDictionary[key] = @YES;

// remove the download state
self.downloadingSectionsDictionary[key] = @NO;

// update the showing state
self.showingSectionsDictionary[key] = @YES;

NSInteger newRowCount = [self.myDataSource tableView:self numberOfRowsInSection:section];
// now do the animation magic to insert the new cells
if (animated && newRowCount <= self.maximumRowCountToStillUseAnimationWhileExpanding) {
[self beginUpdates];

UITableViewCell<UIExpandingTableViewCell> *cell = (UITableViewCell<UIExpandingTableViewCell> *)[self cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:section]];
cell.loading = NO;
[cell setExpansionStyle:UIExpansionStyleExpanded animated:YES];

NSMutableArray *insertArray = [NSMutableArray array];
for (int i = 1; i < newRowCount; i++) {
[insertArray addObject:[NSIndexPath indexPathForRow:i inSection:section] ];
}

[self insertRowsAtIndexPaths:insertArray withRowAnimation:self.reloadAnimation];

[self endUpdates];
} else {
[self reloadDataAndResetExpansionStates:NO];
}

[self.animatingSectionsDictionary removeObjectForKey:@(section)];

[self scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:section]
atScrollPosition:UITableViewScrollPositionTop
animated:animated];


void(^completionBlock)(void) = ^{
if ([self respondsToSelector:@selector(scrollViewDidScroll:)]) {
[self scrollViewDidScroll:self];
}

if ([self.myDelegate respondsToSelector:@selector(tableView:didExpandSection:animated:)]) {
[self.myDelegate tableView:self didExpandSection:section animated:animated];
}
};

if (animated) {
[CATransaction setCompletionBlock:completionBlock];
} else {
Expand All @@ -266,55 +273,58 @@ - (void)collapseSection:(NSInteger)section animated:(BOOL)animated {
// section is not showing, return
return;
}

if ([self.myDelegate respondsToSelector:@selector(tableView:willCollapseSection:animated:)]) {
[self.myDelegate tableView:self willCollapseSection:section animated:animated];
}

[self deselectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:section] animated:NO];

self.animatingSectionsDictionary[key] = @YES;

// update the showing state
self.showingSectionsDictionary[key] = @NO;

NSInteger newRowCount = [self.myDataSource tableView:self numberOfRowsInSection:section];
// now do the animation magic to delete the new cells
if (animated && newRowCount <= self.maximumRowCountToStillUseAnimationWhileExpanding) {
[self beginUpdates];

UITableViewCell<UIExpandingTableViewCell> *cell = (UITableViewCell<UIExpandingTableViewCell> *)[self cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:section]];
cell.loading = NO;
[cell setExpansionStyle:UIExpansionStyleCollapsed animated:YES];

NSMutableArray *deleteArray = [NSMutableArray array];
for (int i = 1; i < newRowCount; i++) {
[deleteArray addObject:[NSIndexPath indexPathForRow:i inSection:section] ];
}

[self deleteRowsAtIndexPaths:deleteArray withRowAnimation:self.reloadAnimation];

[self endUpdates];
} else {
[self reloadDataAndResetExpansionStates:NO];
}

[self.animatingSectionsDictionary removeObjectForKey:@(section)];

[self scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:section]
atScrollPosition:UITableViewScrollPositionTop
animated:animated];


if (![self.myDelegate respondsToSelector:@selector(tableView:shouldAnimateScrollToSection:)] || [self.myDelegate tableView:self shouldAnimateScrollToSection:section]) {
[self scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:section]
atScrollPosition:UITableViewScrollPositionTop
animated:animated];

}

void(^completionBlock)(void) = ^{
if ([self respondsToSelector:@selector(scrollViewDidScroll:)]) {
[self scrollViewDidScroll:self];
}

if ([self.myDelegate respondsToSelector:@selector(tableView:didCollapseSection:animated:)]) {
[self.myDelegate tableView:self didCollapseSection:section animated:animated];
}
};

if (animated) {
[CATransaction setCompletionBlock:completionBlock];
} else {
Expand Down Expand Up @@ -344,19 +354,19 @@ - (void)deleteSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAn
if (nextIndex == NSNotFound) {
nextIndex = indexCount;
}

for (NSInteger i = currentIndex + 1; i < nextIndex; i++) {
NSUInteger newIndex = i - currentShift;
self.expandableSectionsDictionary[@(newIndex)] = @([self.expandableSectionsDictionary[@(i)] boolValue]);
self.showingSectionsDictionary[@(newIndex)] = @([self.showingSectionsDictionary[@(i)] boolValue]);
self.downloadingSectionsDictionary[@(newIndex)] = @([self.downloadingSectionsDictionary[@(i)] boolValue]);
self.animatingSectionsDictionary[@(newIndex)] = @([self.animatingSectionsDictionary[@(i)] boolValue]);
}

currentShift++;
currentIndex = [sections indexLessThanIndex:currentIndex];
}

[super deleteSections:sections withRowAnimation:animation];
}

Expand Down Expand Up @@ -414,7 +424,7 @@ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger
return 0;
}
self.expandableSectionsDictionary[key] = @YES;

if ([self.showingSectionsDictionary[key] boolValue]) {
return [self.myDataSource tableView:tableView numberOfRowsInSection:section];
} else {
Expand Down