IKAsyncViewControllers 1.0

IKAsyncViewControllers 1.0

测试已测试
语言语言 Obj-CObjective C
许可证 MIT
发布上次发布2015 年 6 月

Ian Keen 维护。



  • Ian Keen

一个用于将多个 UIViewControllers 链接在一起以获得最终/单个值的简单 DSL

为什么?

尽可能的情况下,我总是试图创建我的 UIViewControllers,使它们与其他任何非视觉组件具有相同的模块化。它们应该能够插入到一个 UIViewControllers 的 '流' 中,并在最后得到一些结果。换句话说,我的 UIViewControllers 通常很愚蠢,它们可能会接受一些输入并有一些输出,但它们对功能之外的事情一无所知。

示例

设想我们正在创建一个小型联系人应用程序,该应用的 '流' 可能是这样的

  • 显示联系人列表
  • 一旦用户选择某个人,我们就显示该联系人的电话号码列表
  • 一旦用户选择一个电话号码,我们就拨打它。

使用 IKAsyncViewController,这种逻辑可以抽象化,并写成以下形式

-(void)callContact:(UINavigationController *)navController animate:(BOOL)animate {
    navController
    .push(^{ 
        return [ContactListViewController new]; 
    }, animate)
    .then(^(User *user){ 
        return [PhoneNumberViewController newWithUser:user]; 
    }, animate)
    .finally(^(NSString *phoneNumber) {
        NSString *phoneNumberString = [NSString stringWithFormat:@"tel://%@", phoneNumber];
        NSURL *url = [NSURL URLWithString:phoneNumberString];
        [[UIApplication sharedApplication] openURL:url];
    });
    return YES;
}

使用方法

UIViewController

设置一个 UIViewController 来支持此流程很简单

.h

#import <IKAsyncViewControllers/IKAsyncViewController.h>

@interface ViewController : UIViewController <IKAsyncViewController>
@end

.m

#import "IKAsyncViewControllerOutput.h"

@interface ViewController ()
@property (nonatomic, strong) IKAsyncViewControllerOutput *output;
@end

@implementation ViewController
-(void)useOutput:(IKAsyncViewControllerOutput *)output {
    self.output = output;
}

-(IBAction)actionTriggered:(id)sender {
    [self.output output:<output_value>];
}
@end

开始链

使用 UINavigationController 类的方法来启动 IKAsyncViewController 链很容易。给定创建要显示的第一个视图控制器的方法

-(UIViewController<IKAsyncViewController> *)firstViewController { ... }

您可以使用 root 块将其设置为根视图控制器

-(void)startChain:(UINavigationController *)navController animate:(BOOL)animate {
    navController.root(^{ return [self firstViewController]; }, animate);
}

或者您可以使用 push 块将其推送到现有的堆栈中

-(void)startChain:(UINavigationController *)navController animate:(BOOL)animate {
    navController.push(^{ return [self firstViewController]; }, animate);
}

继续链

从一个 IKAsyncViewController 解析值到下一个也很简单。给定创建一个接收某些输入并产生某些输出的 IKAsyncViewController 的方法

-(UIViewController<IKAsyncViewController> *)anotherViewController:(id)input { ... }
-(UIViewController<IKAsyncViewController> *)andAnotherViewController:(id)input { ... }

您可以使用 then

-(void)startChain:(UINavigationController *)navController animate:(BOOL)animate {
    navController.root(^{ return [self firstViewController]; }, animate)
    .then(^(id output) { return [self anotherViewController:output]; }, animate)
    .then(^(id output) { return [self andAnotherViewController:output]; }, animate);
}

或者使用 thenIf 块来有条件地显示一个 IKAsyncViewController。如果谓词为 NO,则将在链中跳过 IKAsyncViewController

-(void)startChain:(UINavigationController *)navController {
    navController.root(^{ return [self firstViewController]; })
    .thenIf([self shouldShowAnother], ^(id output) { return [self anotherViewController:output]; }, animate)
    .then(^(id output) { return [self andAnotherViewController:output]; }, animate);
}
-(BOOL)shouldShowAnother { ... }

完成链

最终的想法是从一系列 IKAsyncViewController 中获得一些最终值,这可以通过 finally 块来实现

-(void)startChain:(UINavigationController *)navController {
    navController.root(^{ return [self firstViewController]; })
    .thenIf([self shouldShowAnother], ^(id output) { return [self anotherViewController:output]; }, animate)
    .then(^(id output) { return [self andAnotherViewController:output]; }, animate)
    .finally(^(id finalValue) {
        //.. do something with finalValue
    });
}
-(BOOL)shouldShowAnother { ... }

什么是 IKAsyncViewControllers。

IKAsyncViewControllers 是一个简单而巧妙的 Domain Specific Language (DSL),可以帮助您思考如何使您的 UIViewControllers 更模块化。当您有一组定义明确的 UIViewControllers,可以将它们串联起来以获得某些输出时,这是一个非常好的工具。

IKAsyncViewControllers 不是什么。

IKAsyncViewControllers 不是 storyboards 的替代品,虽然它可以用于复杂的/多分支导航,但这并不意味着它总是适合这个工作。仔细考虑一下,IKAsyncViewControllers 是否适合您的应用程序。

安装

或通过手动将 IKEvents 子文件夹中的源文件添加到您的项目中

其余...

欢迎提出 Pull Requests!

如果您在项目中使用这个工具,我很想听到您的反馈!

联系

我通常在 iOS Developers 上。您应该去看看它们!