iOS 一種新的修改導航欄樣式的方法(支援iOS10).

weixin_34290000發表於2016-10-03

iOS 一種新的修改導航欄樣式的方法.

開宗明義:

對系統導航欄最底層的UIView加一層CALayer, 通過操作這個自己建立的CALayer來修改導航欄樣式.

修改系統導航欄樣式的幾種方法

  • 1.使用系統的API, 更換導航欄背景圖片
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:@"nav_bg.png"] forBarMetrics:UIBarMetricsDefault];

//或者
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"m_nav"] forBarMetrics:UIBarMetricsDefault];
self.navigationBar.layer.masksToBounds = YES;


優點: 找UI出圖就好了.

缺點: 如果專案中導航欄樣式需要經常變化, 這樣的方式就很麻煩了.需要考慮push和pop的情況. 所以在每個控制器中viewWillAppear和viewDisAppear中都需要寫導航欄樣式的程式碼. 而且沒辦法實現類似QQ中, 滑動時導航欄顏色漸變的效果.

  • 2.在導航欄中加一層UIView.

缺點: 導航欄中插入一層UIView後, 系統提供的側滑返回手勢失效. 系統的返回按鈕不可點選.

一種新的想法

第一種方法, 更換導航欄背景圖片應該是應用最多的方法. 但是在系統更新到iOS10之後. 寫了self.navigationBar.layer.masksToBounds = YES.之後會發現導航欄最上方狀態列的位置, 顏色設定失效了.
觀察發現蘋果在iOS10 的SDK中對導航控制器新增了許多新的API. 可能在增加這些API的同時, 也對導航控制器的機制做了一些修改.

我的手機更新到iOS10之後發現幾個大廠出的app導航欄也出了問題...
處理導航欄問題. 最根本的辦法還是全部自定義.但是自定義寫起來實在太過麻煩. 最好還是能在系統導航欄的基礎上做簡單修改實現我們想要的效果.

為此我想到的辦法是在系統導航欄的各個層次中找到最底層的UIView. 對這一層UIView新增一層CALayer. 首先保證導航欄中其他的UIView全部是透明的. 然後通過操作這個我們建立的CGLayer來達到控制導航欄樣式的目的.

經過我的實驗發現新增CALayer不會影響系統的返回按鈕和系統的側滑返回手勢(話說這個返回手勢做的確實很好用, 很舒服.).

步驟.

  1. 將導航欄的Translate屬性設定為YES.
  2. 在NavigationController中的ViewDidLoad方法中遍歷當前View的SubView找到陣列的"0"號元素.(iOS9的SDK中提供了拿到最底層view的API. 但是app需要支援iOS8. 不能使用這個API.)
  3. 建立一個CALayer.將這個CALayer新增到"0"號元素(它是一個UIView)subLayer中.
  4. 將導航欄中的所有的UIView設定為透明.(用文章開始的第一種方法, 設定透明圖片).
    over. 以後需要設定導航欄顏色, 就對這個CALayer設定顏色即可. 還可以通過操作CALayer實現導航欄顏色漸變等效果.

程式碼.

我的專案中導航欄樣式會發生多次變化. 所以對導航欄使用上面的方法進行了一些簡單封裝.
使用方法. 初始化navigationController之後通過介面給導航欄初始的樣式. 以後如果需要修改導航欄樣式就在push之前修改樣式即可.
程式碼連結.
https://github.com/ddyd369/ZDNavigationController

轉發請註明出處(簡書 行如風).

我的理解有什麼錯漏之處還請指出謝謝

相關文章