From 8c0f99a48c93c318f6e1ae667cacf47d7f164fe3 Mon Sep 17 00:00:00 2001 From: Logan Wright Date: Tue, 7 Apr 2015 16:57:11 -0400 Subject: [PATCH 1/6] lock rows that can not be ordered --- HPReorderTableView/HPReorderTableView.m | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/HPReorderTableView/HPReorderTableView.m b/HPReorderTableView/HPReorderTableView.m index b7d3fc7..d9f7eb7 100644 --- a/HPReorderTableView/HPReorderTableView.m +++ b/HPReorderTableView/HPReorderTableView.m @@ -295,14 +295,16 @@ - (void)removeReorderDragView - (void)reorderCurrentRowToIndexPath:(NSIndexPath*)toIndexPath { - [self beginUpdates]; - [self moveRowAtIndexPath:toIndexPath toIndexPath:_reorderCurrentIndexPath]; // Order is important to keep the empty cell behind - if ([self.dataSource respondsToSelector:@selector(tableView:moveRowAtIndexPath:toIndexPath:)]) - { - [self.dataSource tableView:self moveRowAtIndexPath:_reorderCurrentIndexPath toIndexPath:toIndexPath]; + if ([self canMoveRowAtIndexPath:toIndexPath]) { + [self beginUpdates]; + [self moveRowAtIndexPath:toIndexPath toIndexPath:_reorderCurrentIndexPath]; // Order is important to keep the empty cell behind + if ([self.dataSource respondsToSelector:@selector(tableView:moveRowAtIndexPath:toIndexPath:)]) + { + [self.dataSource tableView:self moveRowAtIndexPath:_reorderCurrentIndexPath toIndexPath:toIndexPath]; + } + _reorderCurrentIndexPath = toIndexPath; + [self endUpdates]; } - _reorderCurrentIndexPath = toIndexPath; - [self endUpdates]; } #pragma mark Subclassing From 864ca52c0dbaad10a476b836d4a428d7796c989c Mon Sep 17 00:00:00 2001 From: Logan Wright Date: Wed, 8 Apr 2015 13:44:48 -0400 Subject: [PATCH 2/6] adding will begin and didbegin calls --- HPReorderTableView/HPReorderTableView.h | 2 ++ HPReorderTableView/HPReorderTableView.m | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/HPReorderTableView/HPReorderTableView.h b/HPReorderTableView/HPReorderTableView.h index 01191d0..50e743e 100644 --- a/HPReorderTableView/HPReorderTableView.h +++ b/HPReorderTableView/HPReorderTableView.h @@ -22,6 +22,8 @@ @protocol HPReorderTableViewDelegate @optional - (void)tableView:(UITableView *)tableView didEndReorderingRowAtIndexPath:(NSIndexPath *)indexPath; +- (void)tableView:(UITableView *)tableView willBeginReorderingRowAtIndexPath:(NSIndexPath *)indexPath; +- (void)tableView:(UITableView *)tableView didBeginReorderingRowAtIndexPath:(NSIndexPath *)indexPath; @end /** diff --git a/HPReorderTableView/HPReorderTableView.m b/HPReorderTableView/HPReorderTableView.m index d9f7eb7..a827274 100644 --- a/HPReorderTableView/HPReorderTableView.m +++ b/HPReorderTableView/HPReorderTableView.m @@ -226,6 +226,9 @@ - (void)didBeginLongPressGestureRecognizer:(UILongPressGestureRecognizer*)gestur return; } + if ([self.delegate respondsToSelector:@selector(tableView:willBeginReorderingRowAtIndexPath:)]) { + [self.delegate tableView:self willBeginReorderingRowAtIndexPath:indexPath]; + } UITableViewCell *cell = [self cellForRowAtIndexPath:indexPath]; [cell setSelected:NO animated:NO]; [cell setHighlighted:NO animated:NO]; @@ -247,6 +250,10 @@ - (void)didBeginLongPressGestureRecognizer:(UILongPressGestureRecognizer*)gestur [self animateShadowOpacityFromValue:0 toValue:_reorderDragView.layer.shadowOpacity]; [UIView animateWithDuration:HPReorderTableViewAnimationDuration animations:^{ _reorderDragView.center = CGPointMake(self.center.x, location.y); + } completion:^(BOOL finished) { + if ([self.delegate respondsToSelector:@selector(tableView:didBeginReorderingRowAtIndexPath:)]) { + [self.delegate tableView:self didBeginReorderingRowAtIndexPath:indexPath]; + } }]; [self reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone]; From c08c38d6b4d23d1cedac2eb75dd612b4c51996d3 Mon Sep 17 00:00:00 2001 From: Ying Quan Tan Date: Thu, 9 Apr 2015 11:51:11 -0400 Subject: [PATCH 3/6] add a way to end a reorder --- HPReorderTableView/HPReorderTableView.h | 6 ++++++ HPReorderTableView/HPReorderTableView.m | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/HPReorderTableView/HPReorderTableView.h b/HPReorderTableView/HPReorderTableView.h index 50e743e..49a4c6d 100644 --- a/HPReorderTableView/HPReorderTableView.h +++ b/HPReorderTableView/HPReorderTableView.h @@ -21,6 +21,7 @@ @protocol HPReorderTableViewDelegate @optional +- (void)tableView:(UITableView *)tableView didCancelReorderingRowAtIndexPath:(NSIndexPath *)indexPath; - (void)tableView:(UITableView *)tableView didEndReorderingRowAtIndexPath:(NSIndexPath *)indexPath; - (void)tableView:(UITableView *)tableView willBeginReorderingRowAtIndexPath:(NSIndexPath *)indexPath; - (void)tableView:(UITableView *)tableView didBeginReorderingRowAtIndexPath:(NSIndexPath *)indexPath; @@ -49,6 +50,11 @@ */ - (void)registerTemporaryEmptyCellClass:(Class)cellClass; +/** + Allow the caller to end any reorder that is in progress. + */ +- (void)endAnyExistingReorder; + @end /** diff --git a/HPReorderTableView/HPReorderTableView.m b/HPReorderTableView/HPReorderTableView.m index a827274..0e20c43 100644 --- a/HPReorderTableView/HPReorderTableView.m +++ b/HPReorderTableView/HPReorderTableView.m @@ -90,6 +90,26 @@ - (void)registerTemporaryEmptyCellClass:(Class)cellClass [self registerClass:cellClass forCellReuseIdentifier:HPReorderTableViewCellReuseIdentifier]; } +- (void)endAnyExistingReorder +{ + if (_reorderCurrentIndexPath) { + // we repeat a bunch of code here that's in didEndLongPressGestureRecognizer, but we also make sure that + // but we don't call reloadRowsAtIndexPaths: on the tableview, since that might cause an out-of-bounds crash + if ([self.delegate respondsToSelector:@selector(tableView:didCancelReorderingRowAtIndexPath:)]) { + [self.delegate tableView:self didCancelReorderingRowAtIndexPath:_reorderCurrentIndexPath]; + } + [self animateShadowOpacityFromValue:_reorderDragView.layer.shadowOpacity toValue:0]; + { // Reset + [_scrollDisplayLink invalidate]; + _scrollDisplayLink = nil; + _scrollRate = 0; + _reorderCurrentIndexPath = nil; + _reorderInitialIndexPath = nil; + } + [self removeReorderDragView]; + } +} + #pragma mark - Actions - (void)recognizeLongPressGestureRecognizer:(UILongPressGestureRecognizer*)gestureRecognizer From a3ff3ea570ea49e790e9e1eacd486a292d1dfcf8 Mon Sep 17 00:00:00 2001 From: LuQuan Intrepid Date: Thu, 23 Apr 2015 13:48:23 -0400 Subject: [PATCH 4/6] add hook to tell when reorder gesture should be cancelled --- HPReorderTableView/HPReorderTableView.h | 4 ++++ HPReorderTableView/HPReorderTableView.m | 9 ++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/HPReorderTableView/HPReorderTableView.h b/HPReorderTableView/HPReorderTableView.h index 49a4c6d..eb12596 100644 --- a/HPReorderTableView/HPReorderTableView.h +++ b/HPReorderTableView/HPReorderTableView.h @@ -25,6 +25,10 @@ - (void)tableView:(UITableView *)tableView didEndReorderingRowAtIndexPath:(NSIndexPath *)indexPath; - (void)tableView:(UITableView *)tableView willBeginReorderingRowAtIndexPath:(NSIndexPath *)indexPath; - (void)tableView:(UITableView *)tableView didBeginReorderingRowAtIndexPath:(NSIndexPath *)indexPath; +/** + * Can this row be allowed to be dragged. As opposed to canMoveRowAtIndexPath where determines is the row can move at all. + */ +- (BOOL)canDragRowAtIndexPath:(NSIndexPath *)indexPath; @end /** diff --git a/HPReorderTableView/HPReorderTableView.m b/HPReorderTableView/HPReorderTableView.m index 0e20c43..a6f44c5 100644 --- a/HPReorderTableView/HPReorderTableView.m +++ b/HPReorderTableView/HPReorderTableView.m @@ -198,6 +198,13 @@ - (BOOL)canMoveRowAtIndexPath:(NSIndexPath*)indexPath return ![self.dataSource respondsToSelector:@selector(tableView:canMoveRowAtIndexPath:)] || [self.dataSource tableView:self canMoveRowAtIndexPath:indexPath]; } +- (BOOL)canDragRowAtIndexPath:(NSIndexPath *)indexPath { + if ([self.delegate respondsToSelector:@selector(canDragRowAtIndexPath:)]) { + return [self.delegate canDragRowAtIndexPath:indexPath]; + } + return YES; +} + - (BOOL)hasRows { NSInteger sectionCount = [self numberOfSections]; @@ -240,7 +247,7 @@ - (void)didBeginLongPressGestureRecognizer:(UILongPressGestureRecognizer*)gestur { const CGPoint location = [gestureRecognizer locationInView:self]; NSIndexPath *indexPath = [self indexPathForRowAtPoint:location]; - if (indexPath == nil || ![self canMoveRowAtIndexPath:indexPath]) + if (indexPath == nil || ![self canMoveRowAtIndexPath:indexPath] || ![self canDragRowAtIndexPath:indexPath]) { HPGestureRecognizerCancel(gestureRecognizer); return; From 1e7f1d64bfa2971d8428034a9f37df6f9ba2c100 Mon Sep 17 00:00:00 2001 From: Ying Quan Tan Date: Mon, 18 May 2015 15:36:44 -0400 Subject: [PATCH 5/6] fix reordering bug --- HPReorderTableView/HPReorderTableView.m | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/HPReorderTableView/HPReorderTableView.m b/HPReorderTableView/HPReorderTableView.m index 0e20c43..76c4513 100644 --- a/HPReorderTableView/HPReorderTableView.m +++ b/HPReorderTableView/HPReorderTableView.m @@ -448,7 +448,9 @@ - (void)updateCurrentLocation:(UILongPressGestureRecognizer *)gesture if ([toIndexPath compare:_reorderCurrentIndexPath] == NSOrderedSame) return; NSInteger originalHeight = _reorderDragView.frame.size.height; - NSInteger toHeight = [self rectForRowAtIndexPath:toIndexPath].size.height; + // original code uses rectForRowAtIndexPath:, but this bugs out when the delegate implements + // estimatedHeightForRowAtIndexPath: + NSInteger toHeight = [self.delegate tableView:self heightForRowAtIndexPath:toIndexPath]; UITableViewCell *toCell = [self cellForRowAtIndexPath:toIndexPath]; const CGPoint toCellLocation = [gesture locationInView:toCell]; From 30b948546e91d75c147b20a91436338da18e0ee5 Mon Sep 17 00:00:00 2001 From: Ying Quan Tan Date: Mon, 18 May 2015 19:09:41 -0400 Subject: [PATCH 6/6] Revert "Merge pull request #3 from LoganWright/ying/fixEstimatedHeights" This reverts commit 1328cf73effff32f929ebee628b3d3fd0dfa2e67, reversing changes made to 61958a3b29c35663cb8499202da232cce338664b. --- HPReorderTableView/HPReorderTableView.m | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/HPReorderTableView/HPReorderTableView.m b/HPReorderTableView/HPReorderTableView.m index c79bc14..a6f44c5 100644 --- a/HPReorderTableView/HPReorderTableView.m +++ b/HPReorderTableView/HPReorderTableView.m @@ -455,9 +455,7 @@ - (void)updateCurrentLocation:(UILongPressGestureRecognizer *)gesture if ([toIndexPath compare:_reorderCurrentIndexPath] == NSOrderedSame) return; NSInteger originalHeight = _reorderDragView.frame.size.height; - // original code uses rectForRowAtIndexPath:, but this bugs out when the delegate implements - // estimatedHeightForRowAtIndexPath: - NSInteger toHeight = [self.delegate tableView:self heightForRowAtIndexPath:toIndexPath]; + NSInteger toHeight = [self rectForRowAtIndexPath:toIndexPath].size.height; UITableViewCell *toCell = [self cellForRowAtIndexPath:toIndexPath]; const CGPoint toCellLocation = [gesture locationInView:toCell];