Implementation of Synchronous Concurrency features for AsyncDisplayKit 2.0

This provides internal features on _ASAsyncTransaction and ASDisplayNode to facilitate
implementing public API that allows clients to choose if they would prefer to block
on the completion of unfinished rendering, rather than allow a placeholder state to
become visible.

The internal features are:
-[_ASAsyncTransaction waitUntilComplete]
-[ASDisplayNode recursivelyEnsureDisplay]

Also provided are two such implementations:
-[ASCellNode setNeverShowPlaceholders:], which integrates with both Tables and Collections
-[ASViewController setNeverShowPlaceholders:], which should work with Nav and Tab controllers.

Lastly, on ASDisplayNode, a new property .shouldBypassEnsureDisplay allows individual node types
to exempt themselves from blocking the main thread on their display.

By implementing the feature at the ASCellNode level rather than ASTableView & ASCollectionView,
developers can retain fine-grained control on display characteristics.  For example, certain
cell types may be appropriate to display to the user with placeholders, whereas others may not.

Follow-up work will include unit tests, revisiting names, and the header locations of definitions.
This commit is contained in:
Scott Goodson
2015-09-27 19:14:36 -07:00
parent c824644482
commit a58844379c
34 changed files with 1109 additions and 37 deletions

View File

@@ -17,6 +17,9 @@
#import "UICollectionViewLayout+ASConvenience.h"
#import "ASInternalHelpers.h"
// FIXME: Temporary nonsense import until method names are finalized and exposed
#import "ASDisplayNode+Subclasses.h"
const static NSUInteger kASCollectionViewAnimationNone = UITableViewRowAnimationNone;
@@ -315,6 +318,16 @@ static BOOL _isInterceptedSelector(SEL sel)
return [[_dataController nodeAtIndexPath:indexPath] calculatedSize];
}
- (ASCellNode *)nodeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return [_dataController nodeAtIndexPath:indexPath];
}
- (NSIndexPath *)indexPathForNode:(ASCellNode *)cellNode
{
return [_dataController indexPathForNode:cellNode];
}
- (NSArray *)visibleNodes
{
NSArray *indexPaths = [self indexPathsForVisibleItems];
@@ -392,11 +405,6 @@ static BOOL _isInterceptedSelector(SEL sel)
[_dataController moveRowAtIndexPath:indexPath toIndexPath:newIndexPath withAnimationOptions:kASCollectionViewAnimationNone];
}
- (ASCellNode *)nodeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return [_dataController nodeAtIndexPath:indexPath];
}
#pragma mark -
#pragma mark Intercepted selectors.
@@ -490,6 +498,11 @@ static BOOL _isInterceptedSelector(SEL sel)
if ([_asyncDelegate respondsToSelector:@selector(collectionView:willDisplayNodeForItemAtIndexPath:)]) {
[_asyncDelegate collectionView:self willDisplayNodeForItemAtIndexPath:indexPath];
}
ASCellNode *cellNode = [self nodeForItemAtIndexPath:indexPath];
if (cellNode.neverShowPlaceholders) {
[cellNode recursivelyEnsureDisplay];
}
}
- (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath