微信 UI 中 tabbar 和 navigation 之间的问题

2015-07-16 01:05:49 +08:00
 tunnyios
PS:更好的排版可以看这里: http://tunnyios.github.io/personal/tabBar_Nav/#section-4

创建一个tabbarController的主界面,childControllers为 ViewController1、ViewController2,如何在ViewController2里面的某一个界面中点击一个按钮 让ViewController2 push到下一个界面 并且让界面显示为该界面。

更形象的例子:可参考微信,在微信界面点击进入聊天框;在通讯录界面,点击相应联系人,然后点击发送消息,进入聊天框。两个方式进入聊天框 左上角的返回键 都是返回tabbar的主界面。

废话不多说直接上核心代码:其实也就是只有一段,就是监听消息按钮的点击事件,做相应的处理。在这里遇到了点问题,一会儿说。

问题代码
-(IBAction)sendMessage
{
//将当前控制器弹出栈
[self.navigationController popToRootViewControllerAnimated:YES];

//取到storyBoard中对应的控制器
self.tabBarController.selectedIndex = 0;
UINavigationController *nav = self.tabBarController.viewControllers[0];

UIStoryboard *mainSB = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
UIViewController *chatVc = [mainSB instantiateViewControllerWithIdentifier:@"chat"];

[nav pushViewController:chatVc animated:YES];
}

问题效果图
http://7xke07.com1.z0.glb.clouddn.com/image/tabBar-Nav-error.gif

原因分析

大家会看到效果图中,发消息的那个控制器已经pop掉了,但是当点击通讯录tabBarItem时,发消息的那个控制器会一闪而过。

原因(个人理解):通过pop方法将控制器弹出栈,会销毁当前控制器,但是在同一个方法里先pop了当前的控制器,紧接着又进行了其他的操作(PS:当还在这个控制器的操作没有执行完的时候,在内存中还被持有在内存中时,就不会被销毁!此处只是个别现象,应该具体问题具体分析),导致控制器没有被立刻销毁。之后点击tabBarItem时,才销毁了控制器,因此会一闪而过;

为什么只有在点击了通讯录tabBarItem时,才会销毁发消息控制器呢?

原因(个人理解):这个是具体情况,因为tabBarController对应有导航控制器,但是pop后,对应A控制器已经被移出栈顶了,但是没有被销毁,所以还显示着。当点击通讯录tabBarItem时,会显示对应导航控制器的栈顶控制器,此时栈顶控制器是B控制器,但是A控制器还压在B控制器上,因此tabBar要显示控制器B,系统会发现A已经不在栈中了,然后销毁了A控制器…

修改后的代码
-(IBAction)sendMessage
{
//取到storyBoard中对应的控制器
self.tabBarController.selectedIndex = 0;
UINavigationController *nav = self.tabBarController.viewControllers[0];

UIStoryboard *mainSB = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
UIViewController *chatVc = [mainSB instantiateViewControllerWithIdentifier:@"chat"];

[nav pushViewController:chatVc animated:YES];

//注意此处:仅仅是将位置换了一下
[self.navigationController popToRootViewControllerAnimated:YES];
}

效果图演示
http://7xke07.com1.z0.glb.clouddn.com/image/tabBar-Nav-ok.gif

DEMO代码分享

链接: http://pan.baidu.com/s/1nttHH7F 密码: zap2
2779 次点击
所在节点    iOS
2 条回复
gonghao
2015-07-16 01:15:09 +08:00
如果问题代码里,将 `[self.navigationController popToRootViewControllerAnimated:YES]; ` 中的 `YES` 改为 `NO` 呢?
tunnyios
2015-07-16 01:17:58 +08:00
@gonghao 改成NO也一样的。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/205987

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX