测试测试 | ✗ |
Lang语言 | Obj-CObjective C |
许可 | MIT |
发布最后发布 | 2014年12月 |
由 Jake Marsh 维护。
这是一个类,我在需要实现 iOS 应用中的“具有状态”的表格视图时总是使用。在这种情况下,当我说“具有状态”时,我指的是具有以下“状态”的表格视图控制器:
如果你在应用中使用 JMStatefulTableViewController
,请将其添加到 此列表 中。
托管在此仓库中的演示项目是您了解如何在您的应用中实现 JMStatefulTableViewController
的第一站,但基本上您只需要从 JMStatefulTableViewController
中继承子类,并在该子类中实现所需的代理方法。
下一段将展示如何实现所需的代理方法的一个示例。
JMStatefulTableViewController
将调用它的 statefulDelegate
,传递它两个块,一个 success
和一个 failure
块,当表格视图需要加载数据时。它还会透明地为您处理将状态改变为 JMStatefulTableViewControllerStateInitialLoading
。
您应该在方法内部编写或调用代码来加载您的一组初始内容,然后调用对应的代码块来处理结果。如果数据加载成功,调用success
块;如果由于某些原因而失败,调用failure
块,可以根据需要传递一个NSError
对象或nil
。
- (void) statefulTableViewControllerWillBeginInitialLoading:(JMStatefulTableViewController *)vc completionBlock:(void (^)())success failure:(void (^)(NSError *error))failure {
// Always do any sort of heavy loading work on a background queue:
dispatch_async(dispatch_get_global_queue(0, DISPATCH_QUEUE_PRIORITY_DEFAULT), ^{
self.catPhotos = [self _loadHilariousCatPhotosFromTheInternet];
// Always call success() on the main queue:
dispatch_async(dispatch_get_main_queue(), ^{
success();
});
});
}
JMStatefulTableViewController
在用户完成“下拉刷新”动作后,将通过该方法调用其statefulDelegate
,并传入两个块,即success
和failure
块。请注意,在这种情况下,success
块要求一个NSIndexPath
对象的数组。
我采用这种方式实现,以便可以轻松地实现我所谓的“正确”的下拉刷新样式加载。在“正确”的下拉刷新加载中,现有内容保持在原位,新内容出现在其上方,而不会对表视图进行任何偏移。这正是Loren Brichter(该概念的原始发明者)最初发明并打算实现的方式。在我看来,这也更有逻辑性。然而,如果您愿意,您可以简单地将nil
空数组或空NSArray
对象传递给NSIndexPath
数组,JMStatefulTableViewController
将优雅地降低性能,用最新内容替换您表视图中的内容。
您应该在方法内部编写或调用代码来加载最新内容(或可选地重新加载一切,如许多应用今天所做的那样),然后调用相应的块来处理结果。如果数据成功加载,调用success
块;如果由于某些原因失败,调用failure
块,可以根据需要传递一个NSError
对象或nil
。
- (void) statefulTableViewControllerWillBeginLoadingFromPullToRefresh:(JMStatefulTableViewController *)vc completionBlock:(void (^)(NSArray *indexPathsToInsert))success failure:(void (^)(NSError *error))failure {
// Always do any sort of heavy loading work on a background queue:
dispatch_async(dispatch_get_global_queue(0, DISPATCH_QUEUE_PRIORITY_DEFAULT), ^{
// Grab what is currently our first photo
CatPhoto *photo = [self.catPhotos objectAtIndex:0];
// Load any newer photos that might have been added on our server
NSArray *catPhotos = [self _loadHilariousCatPhotosFromTheInternetNewerThanPhoto:photo];
// Prepend our self.catPhotos array with these new photos we loaded
self.catPhotos = [catPhotos arrayByAddingObjectsFromArray:self.catPhotos];
// Put together an array of NSIndexPath objects representing
// what the index paths will be of the new rows that will be created
NSMutableArray *a = [NSMutableArray array];
for(NSInteger i = 0; i < loadedBeerStrings.count; i++) {
[a addObject:[NSIndexPath indexPathForRow:i inSection:0]];
}
// Always call success() on the main queue:
dispatch_async(dispatch_get_main_queue(), ^{
// If we didn't want to achieve "proper" pull to refresh behavior, we could just pass `nil` in here:
success([NSArray arrayWithArray:a]);
});
});
}
JMStatefulTableViewController
将在用户将手指滑动到您的表视图底部时调用此方法,传递两个块,即success
和failure
块。
您应该在方法内部编写或调用代码来加载下一组内容,然后调用相应的块来处理结果。如果数据加载成功,调用success
块;如果由于某些原因失败,调用failure
块,可以根据需要传递一个NSError
对象或nil
。
- (void) statefulTableViewControllerWillBeginLoadingNextPage:(JMStatefulTableViewController *)vc completionBlock:(void (^)())success failure:(void (^)(NSError *))failure {
// Always do any sort of heavy loading work on a background queue:
dispatch_async(dispatch_get_global_queue(0, DISPATCH_QUEUE_PRIORITY_DEFAULT), ^{
// Grab what is currently our last photo
CatPhoto *photo = [self.catPhotos lastObject];
// Load any older cat photos from our server
NSArray *catPhotos = [self _loadHilariousCatPhotosFromTheInternetOlderThanPhoto:photo];
// Append the new photos we've loaded to the end of your self.catPhotos array
self.catPhotos = [self.catPhotos arrayByAddingObjectsFromArray:catPhotos];
// Always call success() on the main queue:
dispatch_async(dispatch_get_main_queue(), ^{
success();
});
});
}
JMStatefulTableViewController
将使用此方法调用其statefulDelegate
以确定是否可以加载更多内容。
您应该返回一个值以指示是否还有内容可以加载。这将控制是否显示“正在加载更多”的视觉状态。
- (BOOL) statefulTableViewControllerShouldBeginLoadingNextPage:(JMStatefulTableViewController *)vc {
return [self _areThereAnyMoreHilariousCatPhotosOnTheServer];
}
JMStatefulTableViewController
使用@samvermette出色的SVPullToRefresh
库来实现下拉刷新和无限滚动。它非常可定制,您可以在这里查看有关所有信息的文档。
此仓库中提供的演示应用程序使用这些视图的内建实现。目前,它们只是全宽和全高的纯色视图,以在构建应用时让您有所参考。
您可以分别继承 JMStatefulTableViewLoadingView
、JMStatefulTableViewEmptyView
和 JMStatefulTableViewErrorView
。目前,它们没有提供任何特殊的功能或外观,但在未来它们将模仿这些状态的“系统”外观和感觉。您可以随意使用或弃用它们。
JMStatefulTableViewController
有三个属性
@property (strong, nonatomic) UIView *emptyView;
@property (strong, nonatomic) UIView *loadingView;
@property (strong, nonatomic) UIView *errorView;
您可以将它们设置为任何您希望的 UIView
,以表示这些状态的任何一种。正如我说的,目前,默认情况下,它们并没有什么有用的东西,只是纯色的视图。