mirror of
https://github.com/HackPlan/AsyncDisplayKit.git
synced 2026-05-11 23:12:42 +08:00
Merge in downstream changes.
Introduce `ASTableView`, a UITableView subclass that uses `ASCellNode` instead of UITableViewCell. Add working range support via `ASRangeController`, which observes the visible range, maintains a working range, and handles most ASDK machinery. ASRangeController is loosely-enough coupled that it should be easily adapted to UICollectionView if that's desired in the future. Notable considerations in the ASRangeController architecture: * There's no sense rewriting UITableView -- the real win comes from using nodes instead of UITableViewCells (easily parallelisable computation, large number of cells vs. few table views, etc.). So, use a UITableView with empty cells, using UITableViewCell's contentView as a host for arbitrary node hierarchies. * Instead of lazy-loading cells the instant they're needed by UITableView, load them in advance. Preload a substantial number of nodes in the direction of scroll, as well as a small buffer in the other direction. * Maintain compatibility with UITableView's API, with one primary change -- consumer code yields configured ASCellNodes, not UITableViewCells. * Don't use -tableView:heightForRowAtIndexPath:. Nodes already compute their preferred sizes and cache results for use at layout-time, so ASTableView uses their calculatedSizes directly. * Corollary: ASTableView is only aware of nodes that have been sized. This means that, if a cell appears onscreen, it has layout data and can display a "realistic placeholder", e.g. by making its subnodes' background colour grey. Other improvements: * Remove dead references and update headers (fixes #7, #20). * Rename `-[ASDisplayNode sizeToFit:]` to `-measure:` and fix `constrainedSizeForCalulatedSize` typo (fixes #15). * Rename `-willAppear` and `-didDisappear` to `-willEnterHierarchy` and `-didExitHierarchy`. Remove `-willDisappear` -- it was redundant, and there was no counterpart `-didAppear`. * Rename `viewLoaded` to `nodeLoaded`.
This commit is contained in:
@@ -50,12 +50,12 @@ for (ASDisplayNode *n in @[ nodes ]) {\
|
||||
|
||||
#define XCTAssertNodesLoaded(nodes ...) \
|
||||
for (ASDisplayNode *n in @[ nodes ]) {\
|
||||
XCTAssertTrue(n.isViewLoaded, @"%@ should be loaded", n.name);\
|
||||
XCTAssertTrue(n.nodeLoaded, @"%@ should be loaded", n.name);\
|
||||
}
|
||||
|
||||
#define XCTAssertNodesNotLoaded(nodes ...) \
|
||||
for (ASDisplayNode *n in @[ nodes ]) {\
|
||||
XCTAssertFalse(n.isViewLoaded, @"%@ should not be loaded", n.name);\
|
||||
XCTAssertFalse(n.nodeLoaded, @"%@ should not be loaded", n.name);\
|
||||
}
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ for (ASDisplayNode *n in @[ nodes ]) {\
|
||||
- (void)checkValuesMatchDefaults:(ASDisplayNode *)node isLayerBacked:(BOOL)isLayerBacked
|
||||
{
|
||||
NSString *targetName = isLayerBacked ? @"layer" : @"view";
|
||||
NSString *hasLoadedView = node.isViewLoaded ? @"with view" : [NSString stringWithFormat:@"after loading %@", targetName];
|
||||
NSString *hasLoadedView = node.nodeLoaded ? @"with view" : [NSString stringWithFormat:@"after loading %@", targetName];
|
||||
|
||||
id rgbBlackCGColorIdPtr = (id)[UIColor colorWithRed:0 green:0 blue:0 alpha:1].CGColor;
|
||||
|
||||
@@ -190,7 +190,7 @@ for (ASDisplayNode *n in @[ nodes ]) {\
|
||||
[self checkValuesMatchDefaults:node isLayerBacked:isLayerBacked];
|
||||
|
||||
[node layer]; // Force either view or layer loading
|
||||
XCTAssertTrue(node.isViewLoaded, @"Didn't load view");
|
||||
XCTAssertTrue(node.nodeLoaded, @"Didn't load view");
|
||||
|
||||
// Assert that the values can be fetched from the node after the view is realized.
|
||||
[self checkValuesMatchDefaults:node isLayerBacked:isLayerBacked];
|
||||
@@ -220,7 +220,7 @@ for (ASDisplayNode *n in @[ nodes ]) {\
|
||||
- (void)checkValuesMatchSetValues:(ASDisplayNode *)node isLayerBacked:(BOOL)isLayerBacked
|
||||
{
|
||||
NSString *targetName = isLayerBacked ? @"layer" : @"view";
|
||||
NSString *hasLoadedView = node.isViewLoaded ? @"with view" : [NSString stringWithFormat:@"after loading %@", targetName];
|
||||
NSString *hasLoadedView = node.nodeLoaded ? @"with view" : [NSString stringWithFormat:@"after loading %@", targetName];
|
||||
|
||||
XCTAssertEqual(isLayerBacked, node.isLayerBacked, @"isLayerBacked broken %@", hasLoadedView);
|
||||
XCTAssertEqualObjects((id)[self bogusImage].CGImage, (id)node.contents, @"contents broken %@", hasLoadedView);
|
||||
@@ -853,7 +853,7 @@ static inline BOOL _CGPointEqualToPointWithEpsilon(CGPoint point1, CGPoint point
|
||||
|
||||
DeclareNodeNamed(d);
|
||||
if (loaded) {
|
||||
XCTAssertFalse(d.isViewLoaded, @"Should not yet be loaded");
|
||||
XCTAssertFalse(d.nodeLoaded, @"Should not yet be loaded");
|
||||
}
|
||||
|
||||
// Shut the type mismatch up
|
||||
@@ -1049,8 +1049,8 @@ static inline BOOL _CGPointEqualToPointWithEpsilon(CGPoint point1, CGPoint point
|
||||
XCTAssertTrue(replaceMe.supernode == parent, @"didn't remove old node");
|
||||
XCTAssertTrue(first.supernode == nil, @"oops, added node too soon");
|
||||
XCTAssertTrue(second.supernode == nil, @"oops, added node too soon");
|
||||
XCTAssertFalse(first.isViewLoaded, @"first view loaded too soon");
|
||||
XCTAssertFalse(second.isViewLoaded, @"second view loaded too soon");
|
||||
XCTAssertFalse(first.nodeLoaded, @"first view loaded too soon");
|
||||
XCTAssertFalse(second.nodeLoaded, @"second view loaded too soon");
|
||||
|
||||
// Allow first to complete, but verify that the nodes are nil, indicating cancellation (asserts are in blocks above)
|
||||
dispatch_semaphore_signal(allowFirst);
|
||||
@@ -1115,7 +1115,7 @@ static inline BOOL _CGPointEqualToPointWithEpsilon(CGPoint point1, CGPoint point
|
||||
DeclareNodeNamed(d);
|
||||
d.layerBacked = isLayerBacked;
|
||||
if (loaded) {
|
||||
XCTAssertFalse(d.isViewLoaded, @"Should not yet be loaded");
|
||||
XCTAssertFalse(d.nodeLoaded, @"Should not yet be loaded");
|
||||
}
|
||||
|
||||
// Shut the type mismatch up
|
||||
@@ -1542,7 +1542,7 @@ static inline BOOL _CGPointEqualToPointWithEpsilon(CGPoint point1, CGPoint point
|
||||
ASDisplayNode *scrollNode = [[ASDisplayNode alloc] initWithViewClass:[UIScrollView class]];
|
||||
|
||||
XCTAssertFalse(scrollNode.isLayerBacked, @"Can't be layer backed");
|
||||
XCTAssertFalse(scrollNode.isViewLoaded, @"Shouldn't have a view yet");
|
||||
XCTAssertFalse(scrollNode.nodeLoaded, @"Shouldn't have a view yet");
|
||||
|
||||
scrollNode.frame = CGRectMake(12, 52, 100, 53);
|
||||
scrollNode.alpha = 0.5;
|
||||
@@ -1557,7 +1557,7 @@ static inline BOOL _CGPointEqualToPointWithEpsilon(CGPoint point1, CGPoint point
|
||||
ASDisplayNode *transformNode = [[ASDisplayNode alloc] initWithLayerClass:[CATransformLayer class]];
|
||||
|
||||
XCTAssertTrue(transformNode.isLayerBacked, @"Created with layer class => should be layer-backed by default");
|
||||
XCTAssertFalse(transformNode.isViewLoaded, @"Shouldn't have a view yet");
|
||||
XCTAssertFalse(transformNode.nodeLoaded, @"Shouldn't have a view yet");
|
||||
|
||||
transformNode.frame = CGRectMake(12, 52, 100, 53);
|
||||
transformNode.alpha = 0.5;
|
||||
|
||||
Reference in New Issue
Block a user