您的位置:首页 > 其它

控制器跳转之偷梁换柱

2016-01-19 18:33 197 查看
通常情况下,我们的控制器之间的跳转是这样的:
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要设置成隐藏。



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]];
}


效果动画



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

附demo:TabBarControllerJumpDemo
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: