日常的开发工作中,我们往往对于达成的目的或者要做的事情会有一个主流程,在最初的设计中它或许是这样的。

img1

嗯...

看着好像简洁的样子,然而在实际的业务中,往往从page1到page3需要进行N个逻辑判断处理,可谓是过五关斩六将,而且还每个都是必须的,甚至这些判断里面还有一些是相互关联的,如果你将这些判断后面处理的时候都写在当前的Controller里面,当前的这个Controller就会越来越臃肿,以后你会发现你自己看到这些处理的代码会非常头疼。

img2-1

难道就没有好一点的解决办法?

24D00EC1DFB27CD793066A9619F60B95

使用ModelView的方式来解决这个问题,防止主流程断掉。

img3

那么在代码里面该怎么实现呢?使用一个UINavigationController的分类来解决这个问题

//主流程执行回调bolck
typedef void (^ __nullable TMMModelViewNavigationCompletionHandler)(void);

@interface UINavigationController (ModelView)

//声明block属性
@property(nonatomic,copy)TMMModelViewNavigationCompletionHandler tmm_completionHandler;

//是否是showModel视图
@property(nonatomic,assign)BOOL tmm_isShowModelView;

//关闭showModel视图,如果是showModel视图将返回true
-(BOOL)tmm_dismissViewControllerAnimated:(BOOL)animated;


@end

  • 主流程执行回调bolck:用来链接原本的操作,使流程不断掉。(分类里面加属性,Runtime能搞定,具体看文章最后的demo)
  • 是否是showModel视图一个简单的标记当前的UINavigationController是否是ShowModel视图
  • 关闭showModel视图,如果是showModel视图将返回true:用来关闭showModel视图

使用:

先引入UINavigationController分类头文件

#import "UINavigationController+ModelView.h"

然后在对流程上的操作就行业务逻辑条件判断,如下:

- (IBAction)btclick:(id)sender
{
    if (!self.flag) {
        //不满足条件时需要去的事情的页面
        UIViewController *view = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"page1"];
        [view.view setBackgroundColor:[UIColor whiteColor]];
        [view setTitle:@"Page1"];
        
        //showModel的视图为UINavigationController,便于后继有多个操作依然能进行到底
        UINavigationController *navigation = [[UINavigationController alloc] initWithRootViewController:view];
        __weak ViewController *temp = self;
        [navigation setTmm_completionHandler:^{
            __strong ViewController *sself = temp;
            sself.flag = YES;//条件满足
            [sself btclick:nil];//递归调用当前方法
        }];
        [self showViewController:navigation sender:nil];
    }
    else
    {
        //正常流程满足条件后需要做的事情
        [self callBack];
    }
}

-(void)callBack
{
    NSLog(@"执行完事情了,继续走主流程!");
    UIViewController *view = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"view2"];
    [view.view setBackgroundColor:[UIColor whiteColor]];
    
    [self.navigationController pushViewController:view animated:YES];
}


这样的话,当不满足条件时,将进入带UINavigationController的modelView,如果在modelview的页面中将需要进行的前提条件操作完毕,使用关闭showModel视图的方法关闭modelView,并且自动再调用一次当前的方法(继续流程)。

- (IBAction)closeClick:(id)sender {
    //判断是否是showModel视图
    if(![self.navigationController tmm_dismissViewControllerAnimated:YES])
    {
    //不是showModel视图,按照正常的navigation视图逻辑进行返回。
        [self.navigationController popToRootViewControllerAnimated:YES];
    }
}

2018-01-19-14_56_10

demo地址

写完一看,好像并没有什么卵用,胜聊于无吧~

END