控制器跳转之偷梁换柱

通常情况下,我们的控制器之间的跳转是这样的:
A.Nav -push-> B      B -pop-> A 
A -present-> B         B -dismiss-> A

相互之间都是有层级关系和顺序的。但是,有时候项目中需要实现这样一种情况:
B.Nav -push-> X      X -pop-> A

这样说可能有点抽象,大家可以打开手机看看微信,从微信的通讯录中点击某个联系人,再点击‘发送消息’按钮,直接进入聊天室控制器,再点击聊天室控制器左上角的退出,页面是停留在’微信’页面。

怎么回事?乍一看是偷梁换柱了?实际呢,就是偷梁换柱了!
再仔细看,这些页面的跳转都是以push的效果完成的,而且非常流畅。

在介绍这种实现方法之前,请大家打消一种念头,就是利用通知,让TabBarController做调度。作者亲验,TabBarController做调度不仅达不到流畅的push效果,而且跳转过程中很突兀。

不管微信具体怎么实现,今天介绍一种有效的实现方法:

1. 特别的控制器结构

一般情况下,我们最常用的控制器结构是这样的: TabBarController —> NavigationController —>  viewController.而要实现上述效果,现在需要再增加一层,结构会变成这样:NavigationController —> TabBarController —> NavigationController —>  viewController,如图1所示,要注意的是最外层的NavigationBar要设置成隐藏。
控制器跳转之偷梁换柱_第1张图片

2. 瞒天过海

为什么要变成如此结构呢?那是因为在push的时候需要用到最外层的NavigationController,从控制器B中push到控制器X的时候,不是[B.NavigationController pushViewController:X],而是用最外层的NavigationController来push。这样就达到了让最外层的NavigationController作为宏观调控者。当然,要这样实现,最好做一个单例Manager,调配起来就很方便,push代码如下:
- (void)next {
    Item1SecondViewController *secondViewC = [[Item1SecondViewController alloc] init];
    //注意:这里不是self.navigationController
    [[UIManager sharedInstance].tabbarViewController.navigationController pushViewController:secondViewC animated:YES];
}
这样,在视觉效果上和普通的push一样,实际是用另外一只手在操作。

3. 偷梁换柱

下来要实现从X控制器 pop出来后,停留在控制器A页面。两步:
a. 让tabbarViewController.selectedIndex=0
b.改变里层 NavigationController的控制器堆栈

//偷梁换柱在这里……
- (void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];

    [UIManager sharedInstance].tabbarViewController.selectedIndex = 0;
    [self.navigationController setViewControllers:@[[UIManager sharedInstance].tabbarViewController,self]];
}

效果动画

控制器跳转之偷梁换柱_第2张图片


这样就OK啦。此方法已经在项目中使用了一段时间,是经过考验的,放心尝试吧

附demo: TabBarControllerJumpDemo




你可能感兴趣的:(方法,跳转)