Swift学徒

AsyncDisplayKit 教程(4):Batch Fetching

使用 Batch Fetching 进行无限滚动

每个 App 都会采用某些机制,保证用户浏览到当前列表结尾时,可以从服务器上拉取新的数据。通常通过 ScrollView 的 delegate 方法 scrollViewDidScroll: 监听 content
offset 来进行处理。在 ASDK 中,只需要指定:需要提前多少页时请求数据。

取消 AnimalTableController.m 中 Helpers 类别中的两个方法注释。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@implementation AnimalTableController (Helpers)
- (void)retrieveNextPageWithCompletion:(void (^)(NSArray *))block {
NSArray *moreAnimals = [[NSArray alloc] initWithArray:[self.animals subarrayWithRange:NSMakeRange(0, 5)] copyItems:NO];
// Important: this block must run on the main thread
dispatch_async(dispatch_get_main_queue(), ^{
block(moreAnimals);
});
}
- (void)insertNewRowsInTableNode:(NSArray *)newAnimals {
NSInteger section = 0;
NSMutableArray *indexPaths = [NSMutableArray array];
NSUInteger newTotalNumberOfPhotos = self.animals.count + newAnimals.count;
for (NSUInteger row = self.animals.count; row < newTotalNumberOfPhotos; row++) {
NSIndexPath *path = [NSIndexPath indexPathForRow:row inSection:section];
[indexPaths addObject:path];
}
[self.animals addObjectsFromArray:newAnimals];
[self.tableNode insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone];
}
@end

retrieveNextPageWithCompletion: 方法中可以进行网络调用,而 insertNewRowsInTableNode: 将新的数据添加到 table 中。

viewDidLoad: 方法中加入:

1
self.tableNode.view.leadingScreensForBatching = 1.0; // 默认值是 2.0

将 leadingScreensForBatching 设置为 1.0 表示当用户滚动还剩 1 个全屏就到达页尾时,开始抓取新的一批数据。

在 Delegate 类别中加入这个方法:

1
2
3
- (BOOL)shouldBatchFetchForTableNode:(ASTableNode *)tableNode {
return YES;
}

这个方法告诉表格,在这次批抓取之后是否还可以进行新的批抓取。如果你知道 API 上的数据什么时候结束,返回 NO,表示不用进行新的批抓取了。

然后,继续加入:

1
2
3
4
5
6
7
8
9
10
- (void)tableNode:(ASTableNode *)tableNode willBeginBatchFetchWithContext:(ASBatchContext *)context {
//1
[self retrieveNextPageWithCompletion:^(NSArray *animals) {
//2
[self insertNewRowsInTableNode:animals];
//3
[context completeBatchFetching:YES];
}];
}

这个方法在用户即将滚动到 table 末尾并且 shouldBatchFetchForTableNode: 方法返回 YES 时被调用。
代码解释:

  1. 请求一次新批抓取,以备显示。通常这会从 API 返回一个对象数组。
  2. 在完成块中,用新数据刷新表格。
  3. 调用 completeBatchFetching: ,YES 表示你已经完成这个批次。在本批次抓取完成之前,不会进行新的批次抓取。

运行程序,可以无限滚动。


万恶胖为首 wechat
关注公众号(ID:SwiftBetter),进一步探讨交流。