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知足需求的狀況下也可選用,但這兩個方案較複雜。
相關文章
相關標籤/搜索