最近打算整理優(yōu)化一下項目中對導(dǎo)航欄的顯示與隱藏控制
早期做法
由于前期項目中需要隱藏導(dǎo)航欄的頁面不多,早期采用的方案也比較簡單,遵循誰要隱藏自己處理的原則,在需要隱藏的頁面的viewWillAppear執(zhí)行[self.navigationController setNavigationBarHidden:YES animated:YES],viewWillDisappear執(zhí)行[self.navigationController setNavigationBarHidden:NO animated:YES],前期滿足了需求,但是隨著需要隱藏的頁面越來越多,問題也逐漸暴露
- 需要在
viewWillAppear和viewWillDisappear控制導(dǎo)航欄的地方越來越多,不便于管理和維護 - 容易出現(xiàn)人為疏忽,導(dǎo)致導(dǎo)航欄未按預(yù)期展現(xiàn)
- 切換tabBar的情況下,導(dǎo)航欄有一個向上消失的動畫
升級做法
鑒于早期方案存在的問題,我打算整理一下導(dǎo)航欄的實現(xiàn)方案
我考慮了兩個方案
- 放棄使用原生navigationBar,改用自定義view,靈活控制導(dǎo)航欄的展現(xiàn)
- 優(yōu)化現(xiàn)有導(dǎo)航欄顯示隱藏方案
由于項目已經(jīng)比較大,現(xiàn)在改自定義view成本太高,所以我打算先從現(xiàn)有方案的優(yōu)化開始
優(yōu)化方案
基于早期的NavigationController基類進行擴展
viewDidLoad() {
super.viewDidLoad()
self.delegate = self
}
extension ZYNavigationController: UINavigationControllerDelegate {
func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
// 判斷要顯示的控制器是否是自己
let isHidden = viewController.isKind(of: FourthViewController.self) || viewController.isKind(of: FirstViewController.self)
self.setNavigationBarHidden(isHidden, animated: true)
}
}
遵循UINavigationControllerDelegate,在willShow viewController方法內(nèi)判斷當(dāng)前viewController是否需要隱藏導(dǎo)航欄,并根據(jù)判斷結(jié)果設(shè)置。
這樣就能達到,controller在被加載到navigationController內(nèi),將要展現(xiàn)前,判斷并控制導(dǎo)航欄的顯示或隱藏。
這里還有一個問題需要解決,那就是導(dǎo)航欄被隱藏后,手勢返回功能就會失效,這里就需要我們支持,可以通過interactivePopGestureRecognizer來啟動手勢返回
viewDidLoad() {
super.viewDidLoad()
self.delegate = self
}
extension ZYNavigationController: UINavigationControllerDelegate {
func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
// 判斷要顯示的控制器是否是自己
let isHidden = viewController.isKind(of: FourthViewController.self) || viewController.isKind(of: FirstViewController.self)
self.setNavigationBarHidden(isHidden, animated: true)
if isHidden {
self.interactivePopGestureRecognizer?.delegate = self
self.interactivePopGestureRecognizer?.isEnabled = true
}
}
}