iOS页面转场导航栏样式方案梳理

声明:html

1.背景

在iOS开发中每一个页面都有可能被个性化设计,但若是页面是以push方式进行管理,那么多个视图控制器共享一个导航栏,导航栏的适配显示就是一个问题。所以需基于系统导航进一步调整和修改才能知足需求。本文参考下面两篇博客进行分析梳理。swift

2.关注点

页面样式自定义(包括隐藏或显示导航栏)以后,关注点以下:segmentfault

  1. 导航栏内容Title和Item容易编码维护。
  2. 页面过渡导航栏内容渐变更画(参见系统导航效果)。
  3. 页面过渡导航栏背景颜色变化不突兀。
  4. 支持滑动手势pop。

3.导航配置

  1. 导航栏透明iphone

    self.navigationBar.isTranslucent = true //须要开启半透明
    self.navigationBar.setBackgroundImage(UIImage(), for: .default)
    self.navigationBar.shadowImage = UIImage()
  2. 导航栏隐藏ide

    // 导航栏显示(含animated,不然页面有无导航切换可能会突变,在手势pop时最明显)    
    self.navigationController?.setNavigationBarHidden(true, animated: true)
  3. 导航栏颜色布局

    • 导航栏半透明开启:既然开启半透明通常是想用模糊效果的,所以明显应使用下列第①种:学习

      // ① 半透明开启,此种方式设置颜色有明显模糊效果,展开图层树UINavigatuionBar -> background视图 -> UIVisualEffectView -> UIVisualEffectBackdropView, 发现进行UIVisualEffectBackdropView颜色变化(箭头表明内部子视图),可是由于UIVisualEffectView是模糊控制视图,所以会有模糊效果显现出来
      self.navigationController?.navigationBar.backgroundColor = UIColor.kcRed
      // ② 半透明开启,此种方式设置颜色没有模糊效果,展开图层树UINavigationBar ->background视图 -> imageView, 发现imageView颜色变化(箭头表明内部子视图)
      self.navigationController?.navigationBar.setBackgroundImage(UIImage(color:UIColor.kcRed), for: .default)
      // ③ 半透明开启,此种方式设置颜色有轻微模糊感,但不如第一种那样明显,展开图层树UINavigatuionBar -> background视图 -> UIVisualEffectView -> _UIVisualEffectSubview,发现_UIVisualEffectSubview颜色变化(箭头表明内部子视图),由于UIVisualEffectView视模糊控制视图,所以会有模糊效果显现出来
      self.navigationController?.navigationBar.barTintColor = UIColor.kcRed
    • 导航栏半透明关闭:建议采用第②种动画

      // ① 半透明关闭,此种方式不能设置导航栏背景颜色,展开图层树发现设置backgroundcolor仅仅影响UINavigationBar的颜色,可是UINavigationBar有一个background子视图(默认白色)遮盖了设置的颜色
      self.navigationController?.navigationBar.backgroundColor = UIColor.kcRed
      // ② 半透明关闭,此种方式能够设置导航栏颜色,展开图层树UINavigationBar ->background视图 -> imageView,发现imageView颜色变化(箭头表明内部子视图)
      self.navigationController?.navigationBar.setBackgroundImage(UIImage(color:UIColor.kcRed), for: .default)
      // ③ 半透明关闭,此种方式能够设置导航栏颜色。展开图层树发现是设置UINavigationBar的子视图background的颜色,但根据API语义(barTintColor)明显不是设置背景专属,可能会影响内部子视图颜色,所以通常不建议采用此种方法来设置背景色
      self.navigationController?.navigationBar.barTintColor = UIColor.kcRed
  4. 隐藏导航栏下线ui

    // 展开图层树发现黑线是一个高度为0.33的imageView(iphoneX显示),图层树UINavigationBar ->background视图 -> imageView,颜色为透明度0.3的黑色,
        self.navigationBar.shadowImage = UIImage()

3.方案讨论

  • 方案一编码

    • 方案说明:用系统导航栏,且导航栏颜色控制仅仅在每一个视图控制器viewWillAppear中进行配置,透明导航栏也可使用颜色控制。固然也可根据须要部分页面隐藏导航栏。
    • 存在问题:此方案过于简单,页面过渡和手势滑动时导航栏颜色效果变化突兀。
    • 样例:参见KenshinCui博客的名为原始方式的方案(见其博客代码示例的Demo1)。
    • 关注点:不知足关注点3,页面过渡导航栏背景颜色变化突兀。
  • 方案二

    • 方案说明:隐藏系统导航栏,切换不一样颜色的导航条则只须要隐藏用这个方法隐藏导航条而后自定义一个UINavigationBar增长到导航条的位置(添加一个假的导航条)。不过这种方式的因为隐藏了导航条,那么侧滑返回手势也会消失。透明导航条直接隐藏导航条。
    • 存在问题:①须要本身添加UINavigationBar。②因为隐藏了系统的导航栏,形成侧滑手势丢失。解决方式是从新设置当前控制器的interactivePopGestureRecognizer.delegate=self,可是屡次push、pop会出现界面错乱操做失效的问题(解决方式就是在适当的时候禁用侧滑或者禁止手势shouldReceiveTouch)。
    • 样例:参见KenshinCui博客的方案1(见其博客代码示例的Demo2)。
    • 关注点:因为须要添UINavigationBar因此不知足关注点1;此方案导航栏内容和背景随视图渐进平移,背景不突兀,不知足关注点2,但知足关注点3;对于关注点4须要控制好手势的响应。此方案实现起来复杂,而且导航栏原生的特殊效果没有(自适应调整滚动视图、 iOS 11的大标题特效等),但此方案并无突兀点,不影响需求的话能够采用。
  • 方案三

    • 方案说明:系统导航栏透明,自定义导航栏背景视图,将系统原有导航栏的背景设置为透明色,同时在每一个 ViewController上添加一个View或者 NavigationBar来充当咱们实际看到的导航栏,每一个ViewController一样只须要关心自身的样式便可。固然也可根据须要部分页面隐藏导航栏。
    • 存在问题:基本上知足需求,但和系统原生比较起来,须要本身实现半透明效果,另外可在转场过程当中经过self.transitionCoordinator?.animateAlongsideTransition设置navigationBar透明度。
    • 样例:参见KenshinCui博客的方案2(见其博客代码示例的Demo3)。
    • 关注点:基本知足所列4个关注点。
  • 方案四

    • 方案说明:隐藏导航栏,每一个页面包含一个NavigationController ,每一个页面有2个ViewController和一个NavigationController,一个ViewController交给所属导航管理页面跳转,且其子视图为NavigationController(寄宿到另外一个ViewController)。咱们具体细节内容布局在导航内层那个ViewController。
    • 存在问题:视图结构复杂,过渡时导航内容的没动画,手势处理需谨慎(面临两个导航)。
    • 样例:网传网易云音乐是这样。
    • 关注点:看起来和方案二类似,更好的知足关注点1。不知足关注点2。知足关注点3,若是手势处理好可知足关注点4。相对每一个自身页面而言,导航栏的原生特殊效果能够经过内层NavigationController达到。
  • 方案五

    • 方案说明:使用系统导航栏,页面过渡添加Fake Bar在转场的过程当中隐藏原有的导航栏并添加假的 NavigationBar,当转场结束后删除假的 NavigationBar 并恢复原有的导航栏,这一过程能够经过 Swizzle 的方式完成,而每一个 ViewController 只须要关心自身的样式便可。固然也可根据须要部分页面隐藏导航栏。
    • 存在问题:但在解决 Bug 的时候,Swizzle 这种方式无疑会增长解决问题的时间成本和学习成本。
    • 样例:美团。
    • 关注点:不知足关注点2,其它知足。

4.推荐方案

  • 优先推荐方案3,简单易用;方案3为避免出乱子,须要良好的团队代码规范和完善的技术文档来作辅助。
  • 若是旧项目而且历史问题较多采用方案5。
  • 方案2和方案4知足需求的状况下也可选用,但这两个方案较复杂。
相关文章
相关标签/搜索