RBStatefulTableViewController 1.0.0

RBStatefulTableViewController 1.0.0

测试测试
Lang语言 Obj-CObjective C
许可证 MIT
发布了上次发布2015年5月

Rob Booth维护。




  • eoghain

我创建这个控制器是因为我厌倦了只构建表格视图完成工作后意识到我完全忘记了需要加载数据,或者 heaven forbid 表格视图会显示没有任何数据。我也不想放弃我在 Happiness Path 上的所有工作。然后我突发奇想,通过更改表格视图的委托和数据源类,我可以在非常少的努力下有效地更改状态。所以我开始构建 RBStatefulTableViewController。该控制器非常基础,它保持所有状态的列表,当请求转换时,它会调用当前状态对象的 leaveState,然后将表格视图的数据源和委托移动到请求的状态,并最后在请求的状态上调用 enterStateWithData:。它在这个表格视图的 beginUpdates / endUpdates 块中调用所有这些调用,以便所有动画都能无缝地发生。

此控制器不包含有关哪些状态可以转换到其他状态的逻辑,这一点完全留给实现者。我们只负责移动并帮助您以不同的方式思考您的设置。

设置

Storyboard

将原型单元格添加到 storyboard 中,不要忘记设置 Identifier

storyboard

状态

为表格视图可能进入的每个状态创建一个状态对象。您的状态对象需要实现 StatefulTableViewStateProtocolUITableViewDatasourceUITableViewDelegate 所需的方法。

StateObject 的基本原理是在 enterStateWithData: 方法中添加该对象控制的全部行,并在 leaveState 方法中移除它们。RBStatefulTableViewController 将在它在不同状态之间转换时调用这些方法。由于 UITableView 已知如何处理添加/移除行,只要每个状态在进入和离开调用之间是一致的,您的表格视图就会以适当的方式显示数据。

#import "EmptyState.h"
#import "StateDemoTableViewController.h"

@implementation EmptyState

#pragma mark - StatefulTableViewStateProtocol

- (void)enterStateWithData:(id)data
{
    // Add our rows
    [self.tableView insertRowsAtIndexPaths:@[ [NSIndexPath indexPathForRow:0 inSection:0] ] withRowAnimation:UITableViewRowAnimationBottom];
    [self.tableView setAllowsSelection:NO];
}

- (void)leaveState
{
    // Remove our rows
    [self.tableView deleteRowsAtIndexPaths:@[ [NSIndexPath indexPathForRow:0 inSection:0] ] withRowAnimation:UITableViewRowAnimationTop];
    [self.tableView setAllowsSelection:YES];
}

#pragma mark - UITableViewDatasource

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 1;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"EmptyState"];
    return cell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return tableView.frame.size.height; // Make cell take up full height
}

#pragma mark - UITableViewDelegate

@end

控制器

创建您的控制器,并添加所有它将要管理的状态。别忘了转换到初始状态。

#import "StateDemoTableViewController.h"
#import "EmptyState.h"
#import "LoadingState.h"
#import "PopulatedState.h"


NSString * STATE_DEMO_EMPTY_STATE = @"emptyState";
NSString * STATE_DEMO_LOADING_STATE = @"loadingState";
NSString * STATE_DEMO_POPULATED_STATE = @"populatedState";

@implementation StateDemoTableViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self setState:[[EmptyState alloc] init] forKey:STATE_DEMO_EMPTY_STATE];
    [self setState:[[LoadingState alloc] init] forKey:STATE_DEMO_LOADING_STATE];
    [self setState:[[PopulatedState alloc] init] forKey:STATE_DEMO_POPULATED_STATE];
    [self transitionToState:STATE_DEMO_LOADING_STATE withData:nil];
}

@end