iOS导航结构研究

作者: __Hokuang__ | 来源:发表于2016-01-02 13:16 被阅读541次

    iOS中,能用来导航的ViewController主要是UINavigationControllerUITabBarController两种。很多公司的需求里也有navigation controller和tab bar controller混用的场景。然而对于这两个controller的排列顺序,我一直以来有很大的误解。

    以前我认为,排列顺序只可能有一种,就是

    UITabBarController
      UINavigationController
        UIViewController
      UINavigationController
        UIViewController
    

    以前我们公司做股吧的时候,结构就是这么做的。

    这么做本身没有什么问题,可以满足几乎所有的需求。但是我最近遇到的问题就是,UITabBar需要定制(增加一个center button),而且每个tab里面的第二级及以上层级的ViewController都需要隐藏UITabBar。按照网上通行的做法,就是放一个Button到UITabBarController.view上(注意不是UITabBarController.tabBar),然后需要隐藏tabBar的View Controller的init中,加入self.hidesBottomBarWhenPushed=YES。但是这么一搞的话,每次tabBar隐藏之后再显示,那个加上去的center button都会消失。这也不奇怪,毕竟hack了系统的组件,总会有奇怪的问题。

    为了解决这个问题,我观察了一下新浪微博的导航模式。从push动画中可以看出,新浪微博的UITabBarController应该是在UINavigationController下一级的,证据就是push时,tabBar不是向下隐藏,而是向左移出的。所以我试了一下如下的结构:

    UINavigationController
      UITabBarController
        UIViewController
        UIViewController
        UIViewController
    

    发现其实这样也是可以的。在UIViewController里,self.navigationController也是有值的,说明这个UINavigationController不仅传到了UITabBarController.navigationController,还传到了下面一级。

    不过这样一来,对NavigationItem的定制会出现问题,也就是UITabBarController在切换的时候,不会自动将自己的NavigationItem适配成当前被选中的ViewController的NavigationItem。所以在ViewController中,设置self.navigationItem.title这样的语句是不起作用的。

    我现在想到的一个workaround是,在UIViewController中的viewWillAppear函数里,把self.navigationItem的值复制到self.tabBarController.navigationItem中。不知道有没有更好的办法。

    单NavigationController有很多好处,最显著的就是导航逻辑变得简单了。不需要判断现在到底切在哪个tab下的Navigation中。

    不过呢,这种结构应该在东财的应用里是不适用的。因为它的基础是UITabBar只在最开始出现,第二层级以上的界面都没有tabBar。而东财系列的应用一直以来有非常复杂的tabBar显示逻辑需求,可能自定义tabBar是唯一的选择了。

    相关文章

      网友评论

      • imhui:开发文档建议不要把UITabbarController放在UINavigationController里面使用
        __Hokuang__:@imhui 感觉大家都这么做的样子。

      本文标题:iOS导航结构研究

      本文链接:https://www.haomeiwen.com/subject/svmwhttx.html