Support UITableView interactive reordering

This commit is contained in:
Adlai Holler
2016-09-09 16:05:47 -07:00
parent 4f235a401b
commit b7d66943d7
3 changed files with 49 additions and 0 deletions

View File

@@ -146,6 +146,8 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
unsigned int asyncDataSourceNumberOfSectionsInTableView:1;
unsigned int asyncDataSourceTableViewNodeBlockForRowAtIndexPath:1;
unsigned int asyncDataSourceTableViewNodeForRowAtIndexPath:1;
unsigned int asyncDataSourceTableViewCanMoveRowAtIndexPath:1;
unsigned int asyncDataSourceTableViewMoveRowAtIndexPath:1;
} _asyncDataSourceFlags;
}
@@ -301,6 +303,8 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
_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 = [_asyncDelegate respondsToSelector:@selector(tableView:moveRowAtIndexPath:toIndexPath:)];
// Data source must implement tableView:nodeBlockForRowAtIndexPath: or tableView:nodeForRowAtIndexPath:
ASDisplayNodeAssertTrue(_asyncDataSourceFlags.asyncDataSourceTableViewNodeBlockForRowAtIndexPath || _asyncDataSourceFlags.asyncDataSourceTableViewNodeForRowAtIndexPath);
@@ -660,6 +664,24 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
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;

View File

@@ -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

View File

@@ -898,6 +898,25 @@ NSString * const ASDataControllerRowNodeKind = @"_ASDataControllerRowNodeKind";
return _externalCompletedNodes ? : _completedNodes[ASDataControllerRowNodeKind];
}
- (void)moveCompletedNodeAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath
{
ASDisplayNodeAssertMainThread();
if (_externalCompletedNodes != nil) {
NSMutableArray *oldSection = _externalCompletedNodes[indexPath.section];
ASCellNode *node = oldSection[indexPath.item];
[oldSection removeObjectAtIndex:indexPath.item];
[_externalCompletedNodes[newIndexPath.section] insertObject:node atIndex:newIndexPath.item];
}
NSMutableArray *internalCompletedNodes = _completedNodes[ASDataControllerRowNodeKind];
if (internalCompletedNodes != nil) {
NSMutableArray *oldSection = internalCompletedNodes[indexPath.section];
ASCellNode *node = oldSection[indexPath.item];
[oldSection removeObjectAtIndex:indexPath.item];
[internalCompletedNodes[newIndexPath.section] insertObject:node atIndex:newIndexPath.item];
}
}
#pragma mark - Dealloc
- (void)dealloc