From fb6871ac1478894b84f6d0ffa0b4c7c0224c2793 Mon Sep 17 00:00:00 2001 From: Luke Parham Date: Mon, 11 Jul 2016 09:58:09 -0700 Subject: [PATCH 1/3] scroll node, batch fetch, other tweaks --- _docs/automatic-layout-examples.md | 38 ++++++-- _docs/batch-fetching-api.md | 137 +++++++++++++++++++++++------ _docs/debug-tool-pixel-scaling.md | 30 +++++-- _docs/hit-test-slop.md | 31 +++++-- _docs/image-modification-block.md | 38 +++++++- _docs/implicit-hierarchy-mgmt.md | 32 +++++-- _docs/layer-backing.md | 4 +- _docs/scroll-node.md | 38 +++++++- _docs/subtree-rasterization.md | 2 - static/main.css | 2 +- 10 files changed, 291 insertions(+), 61 deletions(-) diff --git a/_docs/automatic-layout-examples.md b/_docs/automatic-layout-examples.md index 0d43bac9..344d5077 100755 --- a/_docs/automatic-layout-examples.md +++ b/_docs/automatic-layout-examples.md @@ -11,8 +11,11 @@ Three examples in increasing order of complexity. -```objective-c +
+SwiftObjective-C +
+
 - (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constraint
 {
   ASStackLayoutSpec *vStack = [[ASStackLayoutSpec alloc] init];
@@ -29,7 +32,12 @@ Three examples in increasing order of complexity.
 
   return insetSpec;
 }
-```
+
+ +
+
###Discussion @@ -37,7 +45,11 @@ Three examples in increasing order of complexity. -```objective-c +
+SwiftObjective-C + +
+
 - (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize
 {
   // header stack
@@ -71,8 +83,12 @@ Three examples in increasing order of complexity.
 
   return verticalStack;
 }
+
+ +
+
###Discussion @@ -82,7 +98,11 @@ Get the full ASDK project at examples/ASDKgram. -```objective-c +
+SwiftObjective-C + +
+
 - (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize {
 
   ASLayoutSpec *textSpec  = [self textSpec];
@@ -172,7 +192,13 @@ Get the full ASDK project at examples/ASDKgram.
   ASBackgroundLayoutSpec *soldOutLabelOverBackground = [ASBackgroundLayoutSpec backgroundLayoutSpecWithChild:centerSoldOutLabel background:centerSoldOut];
   return soldOutLabelOverBackground;
 }
-```
+
+ +
+
###Discussion + Get the full ASDK project at examples/CatDealsCollectionView. diff --git a/_docs/batch-fetching-api.md b/_docs/batch-fetching-api.md index ba63c6da..9d716230 100644 --- a/_docs/batch-fetching-api.md +++ b/_docs/batch-fetching-api.md @@ -6,51 +6,111 @@ prevPage: hit-test-slop.html nextPage: image-modification-block.html --- -AsyncDisplayKit's Batch Fetching API makes it easy for developers to add fetching of new data in chunks. In case the user scrolled to a specific range of a table or collection view the automatic batch fetching mechanism of ASDK kicks in. +AsyncDisplayKit's Batch Fetching API makes it easy to add fetching chunks of new data. Usually this would be done in a `-scrollViewDidScroll:` method, but ASDK provides a more structured mechanism. -You as a developer can define the point when the batch fetching mechanism should start via the `leadingScreensForBatching` property on an `ASTableView` or `ASCollectionView`. The default value for this property is 2.0. +By default, as a user is scrolling, when they approach the point in the table or collection where they are 2 "screens" away from the end of the current content, the table will try to fetch more data. -To support batch fetching you have to implement two methods in your ASTableView or ASCollectionView delegate object: -The first method you have to implement is for ASTableView delegate: +If you'd like to configure how far away from the end you should be, just change the `leadingScreensForBatching` property on an `ASTableView` or `ASCollectionView` to something else. -`- (BOOL)shouldBatchFetchForTableView:(ASTableView *)tableView` +
+SwiftObjective-C -or for ASCollectionView delegate: +
+
+tableNode.view.leadingScreensForBatching = 3.0;  // overriding default of 2.0
+
+ +
+
-`- (BOOL)shouldBatchFetchForCollectionView:(ASCollectionView *)collectionView` +### Batch Fetching Delegate Methods -In this method you have decide if the batch fetching mechanism should kick in if the user scrolled in batch fetching range or not. Usually this decision is based on if there is still data to fetch or not, based on e.g. previous API calls or some local dataset operations. +The first thing you have to do in order to support batch fetching, is implement a method that decides if it's an appropriate time to load new content or not. -If you return NO from `- (BOOL)shouldBatchFetchForCollectionView:(ASCollectionView *)collectionView`, no new batch fetching process will happen, in case you return YES the batch fetching mechanism will start and the following method is called for your ASTableView delegate: +For tables it would look something like: - - (void)tableView:(ASTableView *)tableView willBeginBatchFetchWithContext:(ASBatchContext *)context; +
+SwiftObjective-C -or for ASCollectionView delegate: - - - (void)collectionView:(ASCollectionView *)collectionView willBeginBatchFetchWithContext:(ASBatchContext *)context; - -First of all, you have to be careful within this method as it's called on a background thread. If you have to do anything on the main thread, you are responsible for dispatching it to the main thread and proceed with work you have to do in process to finish the batch fetch. - -Within `- (void)collectionView:(ASCollectionView *)collectionView willBeginBatchFetchWithContext:(ASBatchContext *)context;` you should do any necessary steps to fetch the next chunk of data e.g. from a local database, an API etc. - -After you finished fetching the next chunk of data, it is very important to let ASDK know that you finished the process. To do that you have to call `completeBatchFetching:` on the `context` object that was passed in with a parameter value of YES. This assures that the whole batch fetching mechanism stays in sync and a next batch fetching cycle can happen. Only by passing YES will the context know to attempt another batch update when necessary. If you pass in NO nothing will happen. - -Here you can see an example how a batch fetching cycle could look like: - -```objective-c -- (BOOL)shouldBatchFetchForTableView:(ASTableView *)tableView +
+
+- (BOOL)shouldBatchFetchForTableView:(ASTableView *)tableView
 {
-  // Decide if the batch fetching mechanism should kick in
-  if (_stillDataToFetch) {
+  if (_weNeedMoreContent) {
     return YES;
   }
+
   return NO;
 }
+
+ +
+
+ +and for collections: + +
+SwiftObjective-C + +
+
+
+- (BOOL)shouldBatchFetchForCollectionView:(ASCollectionView *)collectionView
+{
+  if (_weNeedMoreContent) {
+    return YES;
+  }
+
+  return NO;
+}
+
+ +
+
+ +These methods will be called when the user has scrolled into the batch fetching range, and their answer will determine if another request actually needs to be made or not. Usually this decision is based on if there is still data to fetch. + +If you return NO, then no new batch fetching process will happen. If you return YES, the batch fetching mechanism will start and the following method will be called next. + +`-tableView:willBeginBatchFetchWithContext:` + +or + +`-collectionView:willBeginBatchFetchWithContext:` + +This is where you should actually fetch data, be it from a web API or some local database. + +
+Note: This method will always be called on a background thread. This means, if you need to do any work on the main thread, you should dispatch it to the main thread and then proceed with the work needed in order to finish the batch fetch operation. +
+ +
+SwiftObjective-C + +
+
 - (void)tableView:(ASTableView *)tableView willBeginBatchFetchWithContext:(ASBatchContext *)context 
 {
   // Fetch data most of the time asynchronoulsy from an API or local database
-  NSArray *data = ...;
+  NSArray *newPhotos = [SomeSource getNewPhotos];
 
   // Insert data into table or collection view
   [self insertNewRowsInTableView:newPhotos];
@@ -61,9 +121,28 @@ Here you can see an example how a batch fetching cycle could look like:
   // Properly finish the batch fetch
   [context completeBatchFetching:YES]
 }
-```
+
+ +
+
+ +Once you've finished fetching your data, it is very important to let ASDK know that you have finished the process. To do that, you need to call `-completeBatchFetching:` on the `context` object that was passed in with a parameter value of `YES`. This assures that the whole batch fetching mechanism stays in sync and the next batch fetching cycle can happen. Only by passing `YES` will the context know to attempt another batch update when necessary. + +Check out the following sample apps to see the batch fetching API in action: