Skip to content
12 changes: 12 additions & 0 deletions HPReorderTableView/HPReorderTableView.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,14 @@

@protocol HPReorderTableViewDelegate <UITableViewDelegate>
@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;
/**
* 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

/**
Expand All @@ -47,6 +54,11 @@
*/
- (void)registerTemporaryEmptyCellClass:(Class)cellClass;

/**
Allow the caller to end any reorder that is in progress.
*/
- (void)endAnyExistingReorder;

@end

/**
Expand Down
52 changes: 44 additions & 8 deletions HPReorderTableView/HPReorderTableView.m
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -178,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];
Expand Down Expand Up @@ -220,12 +247,15 @@ - (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;
}

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];
Expand All @@ -247,6 +277,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];
Expand Down Expand Up @@ -295,14 +329,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
Expand Down