JMStatefulTableViewController 0.1.2

JMStatefulTableViewController 0.1.2

测试测试
Lang语言 Obj-CObjective C
许可 MIT
发布最后发布2014年12月

Jake Marsh 维护。



  • 作者
  • 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,并传入两个块,即successfailure块。请注意,在这种情况下,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将在用户将手指滑动到您的表视图底部时调用此方法,传递两个块,即successfailure块。

您应该在方法内部编写或调用代码来加载下一组内容,然后调用相应的块来处理结果。如果数据加载成功,调用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库来实现下拉刷新和无限滚动。它非常可定制,您可以在这里查看有关所有信息的文档。

空、加载和错误视图

此仓库中提供的演示应用程序使用这些视图的内建实现。目前,它们只是全宽和全高的纯色视图,以在构建应用时让您有所参考。

您可以分别继承 JMStatefulTableViewLoadingViewJMStatefulTableViewEmptyViewJMStatefulTableViewErrorView。目前,它们没有提供任何特殊的功能或外观,但在未来它们将模仿这些状态的“系统”外观和感觉。您可以随意使用或弃用它们。

JMStatefulTableViewController 有三个属性

@property (strong, nonatomic) UIView *emptyView;
@property (strong, nonatomic) UIView *loadingView;
@property (strong, nonatomic) UIView *errorView;

您可以将它们设置为任何您希望的 UIView,以表示这些状态的任何一种。正如我说的,目前,默认情况下,它们并没有什么有用的东西,只是纯色的视图。

添加到您的项目