diff --git a/SLExpandableTableView/SLExpandableTableView.h b/SLExpandableTableView/SLExpandableTableView.h index ff27fd7..eadd996 100644 --- a/SLExpandableTableView/SLExpandableTableView.h +++ b/SLExpandableTableView/SLExpandableTableView.h @@ -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 diff --git a/SLExpandableTableView/SLExpandableTableView.m b/SLExpandableTableView/SLExpandableTableView.m index ab1ecf9..2fb5178 100644 --- a/SLExpandableTableView/SLExpandableTableView.m +++ b/SLExpandableTableView/SLExpandableTableView.m @@ -44,8 +44,10 @@ @implementation SLExpandableTableView } - (void)setDelegate:(id)delegate { - _myDelegate = delegate; - [super setDelegate:self]; + if (delegate != nil){ + _myDelegate = delegate; + [super setDelegate:self]; + } } - (id)dataSource { @@ -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]; } @@ -100,7 +102,7 @@ - (id)forwardingTargetForSelector:(SEL)aSelector } else if (protocol_containsSelector(@protocol(UITableViewDelegate), aSelector)) { return _myDelegate; } - + return [super forwardingTargetForSelector:aSelector]; } @@ -132,10 +134,10 @@ - (void)commonInit { - (void)awakeFromNib { [super awakeFromNib]; - + _storedTableHeaderView = self.tableHeaderView; _storedTableFooterView = self.tableFooterView; - + self.tableHeaderView = self.tableHeaderView; self.tableFooterView = self.tableFooterView; } @@ -165,7 +167,7 @@ - (void)reloadDataAndResetExpansionStates:(BOOL)resetFlag { if (resetFlag) { [self _resetExpansionStates]; } - + if (self.onlyDisplayHeaderAndFooterViewIfTableViewIsNotEmpty) { if ([self numberOfSections] > 0) { if ([super tableFooterView] != self.storedTableFooterView) { @@ -183,7 +185,7 @@ - (void)reloadDataAndResetExpansionStates:(BOOL)resetFlag { [super setTableHeaderView:self.storedTableHeaderView]; } } - + [super reloadData]; } @@ -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 *cell = (UITableViewCell *)[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 { @@ -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 *cell = (UITableViewCell *)[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 { @@ -344,7 +354,7 @@ - (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]); @@ -352,11 +362,11 @@ - (void)deleteSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAn self.downloadingSectionsDictionary[@(newIndex)] = @([self.downloadingSectionsDictionary[@(i)] boolValue]); self.animatingSectionsDictionary[@(newIndex)] = @([self.animatingSectionsDictionary[@(i)] boolValue]); } - + currentShift++; currentIndex = [sections indexLessThanIndex:currentIndex]; } - + [super deleteSections:sections withRowAnimation:animation]; } @@ -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 {