Skip to content
This repository has been archived by the owner on Feb 2, 2023. It is now read-only.

Commit

Permalink
[ASTableView] Add Support for Interactive Reordering (#2221)
Browse files Browse the repository at this point in the history
  • Loading branch information
Adlai Holler authored and Adlai-Holler committed Sep 15, 2016
1 parent d9a16f2 commit ad17f61
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 0 deletions.
22 changes: 22 additions & 0 deletions AsyncDisplayKit/ASTableView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ @interface ASTableView () <ASRangeControllerDataSource, ASRangeControllerDelegat
unsigned int asyncDataSourceNumberOfSectionsInTableView:1;
unsigned int asyncDataSourceTableViewNodeBlockForRowAtIndexPath:1;
unsigned int asyncDataSourceTableViewNodeForRowAtIndexPath:1;
unsigned int asyncDataSourceTableViewCanMoveRowAtIndexPath:1;
unsigned int asyncDataSourceTableViewMoveRowAtIndexPath:1;
} _asyncDataSourceFlags;
}

Expand Down Expand Up @@ -301,6 +303,8 @@ - (void)setAsyncDataSource:(id<ASTableViewDataSource>)asyncDataSource
_asyncDataSourceFlags.asyncDataSourceNumberOfSectionsInTableView = [_asyncDataSource respondsToSelector:@selector(numberOfSectionsInTableView:)];
_asyncDataSourceFlags.asyncDataSourceTableViewNodeForRowAtIndexPath = [_asyncDataSource respondsToSelector:@selector(tableView:nodeForRowAtIndexPath:)];
_asyncDataSourceFlags.asyncDataSourceTableViewNodeBlockForRowAtIndexPath = [_asyncDataSource respondsToSelector:@selector(tableView:nodeBlockForRowAtIndexPath:)];
_asyncDataSourceFlags.asyncDataSourceTableViewCanMoveRowAtIndexPath = [_asyncDataSource respondsToSelector:@selector(tableView:canMoveRowAtIndexPath:)];
_asyncDataSourceFlags.asyncDataSourceTableViewMoveRowAtIndexPath = [_asyncDataSource respondsToSelector:@selector(tableView:moveRowAtIndexPath:toIndexPath:)];

// Data source must implement tableView:nodeBlockForRowAtIndexPath: or tableView:nodeForRowAtIndexPath:
ASDisplayNodeAssertTrue(_asyncDataSourceFlags.asyncDataSourceTableViewNodeBlockForRowAtIndexPath || _asyncDataSourceFlags.asyncDataSourceTableViewNodeForRowAtIndexPath);
Expand Down Expand Up @@ -660,6 +664,24 @@ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger
return [_dataController numberOfRowsInSection:section];
}

- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
if (_asyncDataSourceFlags.asyncDataSourceTableViewCanMoveRowAtIndexPath) {
return [_asyncDataSource tableView:self canMoveRowAtIndexPath:indexPath];
} else {
return NO;
}
}

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
{
if (_asyncDataSourceFlags.asyncDataSourceTableViewMoveRowAtIndexPath) {
[_asyncDataSource tableView:self moveRowAtIndexPath:sourceIndexPath toIndexPath:destinationIndexPath];
}
// Move node after informing data source in case they call nodeAtIndexPath:
[_dataController moveCompletedNodeAtIndexPath:sourceIndexPath toIndexPath:destinationIndexPath];
}

- (void)tableView:(UITableView *)tableView willDisplayCell:(_ASTableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
_pendingVisibleIndexPath = indexPath;
Expand Down
8 changes: 8 additions & 0 deletions AsyncDisplayKit/Details/ASDataController.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,14 @@ FOUNDATION_EXPORT NSString * const ASDataControllerRowNodeKind;
*/
- (NSArray<NSArray <ASCellNode *> *> *)completedNodes;

/**
* Immediately move this item. This is called by ASTableView when the user has finished an interactive
* item move and the table view is requesting a model update.
*
* This must be called on the main thread.
*/
- (void)moveCompletedNodeAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath;

@end

NS_ASSUME_NONNULL_END
7 changes: 7 additions & 0 deletions AsyncDisplayKit/Details/ASDataController.mm
Original file line number Diff line number Diff line change
Expand Up @@ -898,6 +898,13 @@ - (NSArray *)completedNodes
return _externalCompletedNodes ? : _completedNodes[ASDataControllerRowNodeKind];
}

- (void)moveCompletedNodeAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath
{
ASDisplayNodeAssertMainThread();
ASMoveElementInTwoDimensionalArray(_externalCompletedNodes, indexPath, newIndexPath);
ASMoveElementInTwoDimensionalArray(_completedNodes[ASDataControllerRowNodeKind], indexPath, newIndexPath);
}

#pragma mark - Dealloc

- (void)dealloc
Expand Down
4 changes: 4 additions & 0 deletions AsyncDisplayKit/Details/ASDelegateProxy.m
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ - (BOOL)interceptsSelector:(SEL)selector
// handled by ASRangeController
selector == @selector(numberOfSectionsInTableView:) ||
selector == @selector(tableView:numberOfRowsInSection:) ||

// reordering support
selector == @selector(tableView:canMoveRowAtIndexPath:) ||
selector == @selector(tableView:moveRowAtIndexPath:toIndexPath:) ||

// used for ASCellNode visibility
selector == @selector(scrollViewDidScroll:) ||
Expand Down
5 changes: 5 additions & 0 deletions AsyncDisplayKit/Private/ASMultidimensionalArrayUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ extern NSArray *ASFindElementsInMultidimensionalArrayAtIndexPaths(NSMutableArray
*/
extern NSArray *ASIndexPathsForMultidimensionalArrayAtIndexSet(NSArray *multidimensionalArray, NSIndexSet *indexSet);

/**
* Moves the object at `sourceIndexPath` to `destinationIndexPath`.
*/
extern void ASMoveElementInTwoDimensionalArray(NSMutableArray *mutableArray, NSIndexPath *sourceIndexPath, NSIndexPath *destinationIndexPath);

/**
* Return the index paths of the given multidimensional array that are present in the given index paths array.
*/
Expand Down
9 changes: 9 additions & 0 deletions AsyncDisplayKit/Private/ASMultidimensionalArrayUtils.mm
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,15 @@ void ASDeleteElementsInMultidimensionalArrayAtIndexPaths(NSMutableArray *mutable
return res;
}

void ASMoveElementInTwoDimensionalArray(NSMutableArray *mutableArray, NSIndexPath *sourceIndexPath, NSIndexPath *destinationIndexPath)
{
NSMutableArray *oldSection = mutableArray[sourceIndexPath.section];
NSInteger oldItem = sourceIndexPath.item;
id object = oldSection[oldItem];
[oldSection removeObjectAtIndex:oldItem];
[mutableArray[destinationIndexPath.section] insertObject:object atIndex:destinationIndexPath.item];
}

NSArray<NSIndexPath *> *ASIndexPathsInMultidimensionalArrayIntersectingIndexPaths(NSArray *multidimensionalArray, NSArray<NSIndexPath *> *indexPaths)
{
NSMutableArray *res = [NSMutableArray array];
Expand Down

0 comments on commit ad17f61

Please sign in to comment.