Add scrollToItem: Method to Node, Handle Section Index Paths (#2462)

* Add scrollToItem: method to node, handle section index paths

* Update ASPagerNode.mm to use the node version

* Add some docs
This commit is contained in:
Adlai Holler
2016-10-26 12:48:25 -07:00
committed by GitHub
parent d4af95c9f1
commit 627d146a5a
11 changed files with 122 additions and 49 deletions

View File

@@ -136,6 +136,17 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeMode:(ASLayoutRangeMode)rangeMode rangeType:(ASLayoutRangeType)rangeType;
/**
* Scrolls the collection to the given item.
*
* @param indexPath The index path of the item.
* @param scrollPosition Where the item should end up after the scroll.
* @param animated Whether the scroll should be animated or not.
*
* This method must be called on the main thread.
*/
- (void)scrollToItemAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UICollectionViewScrollPosition)scrollPosition animated:(BOOL)animated;
#pragma mark - Editing
/**

View File

@@ -335,6 +335,20 @@
[self.view deselectItemAtIndexPath:indexPath animated:animated];
}
- (void)scrollToItemAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UICollectionViewScrollPosition)scrollPosition animated:(BOOL)animated
{
ASDisplayNodeAssertMainThread();
ASCollectionView *collectionView = self.view;
indexPath = [collectionView convertIndexPathFromCollectionNode:indexPath waitingIfNeeded:YES];
if (indexPath != nil) {
[collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:scrollPosition animated:animated];
} else {
NSLog(@"Failed to scroll to item at index path %@ because the item never reached the view.", indexPath);
}
}
#pragma mark - Querying Data
- (void)reloadDataInitiallyIfNeeded

View File

@@ -205,6 +205,15 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeMode:(ASLayoutRangeMode)rangeMode rangeType:(ASLayoutRangeType)rangeType ASDISPLAYNODE_DEPRECATED_MSG("Use ASCollectionNode method instead.");
/**
* Scrolls the collection to the given item.
*
* @param indexPath The index path of the item.
* @param scrollPosition Where the row should end up after the scroll.
* @param animated Whether the scroll should be animated or not.
*/
- (void)scrollToItemAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UICollectionViewScrollPosition)scrollPosition animated:(BOOL)animated ASDISPLAYNODE_DEPRECATED_MSG("Use ASCollectionNode method instead.");
/**
* Perform a batch of updates asynchronously, optionally disabling all animations in the batch. This method must be called from the main thread.
* The asyncDataSource must be updated to reflect the changes before the update block completes.

View File

@@ -555,6 +555,11 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell";
- (NSIndexPath *)convertIndexPathFromCollectionNode:(NSIndexPath *)indexPath waitingIfNeeded:(BOOL)wait
{
// If this is a section index path, we don't currently have a method
// to do a mapping.
if (indexPath.item == NSNotFound) {
return indexPath;
} else {
ASCellNode *node = [_dataController nodeAtIndexPath:indexPath];
NSIndexPath *viewIndexPath = [self indexPathForNode:node];
if (viewIndexPath == nil && wait) {
@@ -562,12 +567,19 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell";
viewIndexPath = [self indexPathForNode:node];
}
return viewIndexPath;
}
}
- (NSIndexPath *)convertIndexPathToCollectionNode:(NSIndexPath *)indexPath
{
// If this is a section index path, we don't currently have a method
// to do a mapping.
if (indexPath.item == NSNotFound) {
return indexPath;
} else {
ASCellNode *node = [self nodeForItemAtIndexPath:indexPath];
return [_dataController indexPathForNode:node];
}
}
- (ASCellNode *)supplementaryNodeForElementKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath
@@ -596,23 +608,6 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell";
return visibleNodes;
}
/**
* TODO: This method was built when the distinction between data source
* index paths and view index paths was unclear. For compatibility, it
* still expects data source index paths for the time being.
*/
- (void)scrollToItemAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UICollectionViewScrollPosition)scrollPosition animated:(BOOL)animated
{
ASDisplayNodeAssertMainThread();
NSIndexPath *viewIndexPath = [self convertIndexPathFromCollectionNode:indexPath waitingIfNeeded:YES];
if (viewIndexPath != nil) {
[super scrollToItemAtIndexPath:viewIndexPath atScrollPosition:scrollPosition animated:animated];
} else {
NSLog(@"Warning: Ignoring request to scroll to item at index path %@ because the item did not reach the collection view.", indexPath);
}
}
/**
* TODO: This method was built when the distinction between data source
* index paths and view index paths was unclear. For compatibility, it

View File

@@ -101,7 +101,7 @@
- (void)scrollToPageAtIndex:(NSInteger)index animated:(BOOL)animated
{
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:index inSection:0];
[self.view scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionLeft animated:animated];
[self scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionLeft animated:animated];
}
- (ASCellNode *)nodeForPageAtIndex:(NSInteger)index

View File

@@ -104,6 +104,17 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeMode:(ASLayoutRangeMode)rangeMode rangeType:(ASLayoutRangeType)rangeType;
/**
* Scrolls the table to the given row.
*
* @param indexPath The index path of the row.
* @param scrollPosition Where the row should end up after the scroll.
* @param animated Whether the scroll should be animated or not.
*
* This method must be called on the main thread.
*/
- (void)scrollToRowAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UITableViewScrollPosition)scrollPosition animated:(BOOL)animated;
/**
* Reload everything from scratch, destroying the working range and all cached nodes.
*

View File

@@ -359,6 +359,20 @@ ASEnvironmentCollectionTableSetEnvironmentState(_environmentStateLock)
[self.view deselectRowAtIndexPath:indexPath animated:animated];
}
- (void)scrollToRowAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UITableViewScrollPosition)scrollPosition animated:(BOOL)animated
{
ASDisplayNodeAssertMainThread();
ASTableView *tableView = self.view;
indexPath = [tableView convertIndexPathFromTableNode:indexPath waitingIfNeeded:YES];
if (indexPath != nil) {
[tableView scrollToRowAtIndexPath:indexPath atScrollPosition:scrollPosition animated:animated];
} else {
NSLog(@"Failed to scroll to row at index path %@ because the row never reached the view.", indexPath);
}
}
#pragma mark - Querying Data
- (void)reloadDataInitiallyIfNeeded

View File

@@ -124,6 +124,15 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeMode:(ASLayoutRangeMode)rangeMode rangeType:(ASLayoutRangeType)rangeType ASDISPLAYNODE_DEPRECATED_MSG("Use ASTableNode method instead.");
/**
* Scrolls the table to the given row.
*
* @param indexPath The index path of the row.
* @param scrollPosition Where the row should end up after the scroll.
* @param animated Whether the scroll should be animated or not.
*/
- (void)scrollToRowAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UITableViewScrollPosition)scrollPosition animated:(BOOL)animated ASDISPLAYNODE_DEPRECATED_MSG("Use ASTableNode method instead.");
/**
* Similar to -visibleCells.
*

View File

@@ -464,14 +464,26 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
- (NSIndexPath *)convertIndexPathFromTableNode:(NSIndexPath *)indexPath waitingIfNeeded:(BOOL)wait
{
// If this is a section index path, we don't currently have a method
// to do a mapping.
if (indexPath.row == NSNotFound) {
return indexPath;
} else {
ASCellNode *node = [_dataController nodeAtIndexPath:indexPath];
return [self indexPathForNode:node waitingIfNeeded:wait];
}
}
- (NSIndexPath *)convertIndexPathToTableNode:(NSIndexPath *)indexPath
{
// If this is a section index path, we don't currently have a method
// to do a mapping.
if (indexPath.row == NSNotFound) {
return indexPath;
} else {
ASCellNode *node = [self nodeForRowAtIndexPath:indexPath];
return [_dataController indexPathForNode:node];
}
}
- (NSIndexPath *)indexPathForNode:(ASCellNode *)cellNode
@@ -528,25 +540,6 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
[_dataController waitUntilAllUpdatesAreCommitted];
}
/**
* TODO: This method was built when the distinction between data source
* index paths and view index paths was unclear. For compatibility, it
* still expects data source index paths for the time being.
* When the behavior is changed (to use the view index path directly)
* we should also remove the @c convertIndexPathFromTableNode: method.
*/
- (void)scrollToRowAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UITableViewScrollPosition)scrollPosition animated:(BOOL)animated
{
ASDisplayNodeAssertMainThread();
indexPath = [self convertIndexPathFromTableNode:indexPath waitingIfNeeded:YES];
if (indexPath != nil) {
[super scrollToRowAtIndexPath:indexPath atScrollPosition:scrollPosition animated:animated];
} else {
NSLog(@"Warning: Ignoring request to scroll to row at index path %@ because the item did not reach the table view.", indexPath);
}
}
/**
* TODO: This method was built when the distinction between data source
* index paths and view index paths was unclear. For compatibility, it

View File

@@ -37,4 +37,12 @@
/// Set YES and we'll log every time we call [super insertRows…] etc
@property (nonatomic) BOOL test_enableSuperUpdateCallLogging;
/**
* Attempt to get the view-layer index path for the row with the given index path.
*
* @param indexPath The index path of the row.
* @param wait If the item hasn't reached the view yet, this attempts to wait for updates to commit.
*/
- (NSIndexPath *)convertIndexPathFromTableNode:(NSIndexPath *)indexPath waitingIfNeeded:(BOOL)wait;
@end

View File

@@ -25,6 +25,15 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, weak, readwrite) ASCollectionNode *collectionNode;
@property (nonatomic, strong, readonly) ASDataController *dataController;
@property (nonatomic, strong, readonly) ASRangeController *rangeController;
/**
* Attempt to get the view-layer index path for the item with the given index path.
*
* @param indexPath The index path of the item.
* @param wait If the item hasn't reached the view yet, this attempts to wait for updates to commit.
*/
- (nullable NSIndexPath *)convertIndexPathFromCollectionNode:(NSIndexPath *)indexPath waitingIfNeeded:(BOOL)wait;
@end
NS_ASSUME_NONNULL_END