转载

控制器跳转之偷梁换柱

通常情况下,我们的控制器之间的跳转是这样的:

A.Nav -push-> B      B -pop-> A 

A -present-> B       B -dismiss-> A

相互之间都是有层级关系和顺序的。但是,有时候项目中需要实现这样一种情况:

B.Nav -push-> X      X -pop-> A

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

怎么回事?乍一看是偷梁换柱了?实际呢,就是偷梁换柱了!

再仔细看,这些页面的跳转都是以push的效果完成的,而且非常流畅。

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

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

1.特别的控制器结构

一般情况下,我们最常用的控制器结构是这样的: TabBarController —> NavigationController —>  viewController.而要实现上述效果,现在需要再增加一层,结构会变成这样:NavigationController —> TabBarController —> NavigationController —>  viewController,如下图所示,要注意的是最外层的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页面。两步:

1)tabbarViewController.selectedIndex=0

2)改变里层 NavigationController的控制器堆栈

//偷梁换柱在这里…… - (void)viewDidAppear:(BOOL)animated{     [super viewDidAppear:animated];          [UIManager sharedInstance].tabbarViewController.selectedIndex = 0;     [self.navigationController setViewControllers:@[[UIManager sharedInstance].tabbarViewController,self]]; }

附上一组效果动画:

控制器跳转之偷梁换柱

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

附demo: TabBarControllerJumpDemo

原文  http://www.cocoachina.com/ios/20160121/15057.html
正文到此结束
Loading...