聲明:我爲這個框架寫了四篇文章:git
第一篇:[iOS]UINavigationController全屏pop之爲每一個控制器自定義UINavigationBargithub
第二篇:[iOS]UINavigationController全屏pop之爲每一個控制器添加底部聯動視圖架構
✅ 全屏 pop 手勢支持性能
✅ 全屏 push 到綁定的控制器支持動畫
✅ 爲每一個控制器定製 UINavigationBar 支持(包括設置顏色和透明度等)3d
✅ 爲每一個控制器添加底部聯動視圖支持code
✅ 自定義 pop 手勢範圍支持(從屏幕最左側開始計算寬度)cdn
✅ 爲單個控制器關閉 pop 手勢支持
✅ 爲全部控制器關閉 pop 手勢支持
❤️ 噹噹前控制器使用 AVPlayer 播放視頻的時候, 使用自定義的 pop 動畫以保證 AVPlayer 流暢播放.
說明:有不少同窗,包括你能看到,留言欄裏也有同窗說原做者不推薦使用這個框架。而後就來問我,是否能在本身的項目裏引入這個框架。從技術的角度來講,我我的的想法是,你要嘗試本身去衡量。可能不少同窗都看到原做者不推薦,可是卻沒注意不推薦的緣由:「細節問題會比這個完善不少」。我不解釋,只把緣由單獨貼出來了。補充一點,凡是我在本身的項目中使用碰到的細節問題,都已經修復好了。
有一個同窗擔憂性能問題,他的擔憂是有依據的,由於畢竟通過包裝處理之後,之前每次只須要壓入一個控制器到棧,如今是每次壓入三個。其實碰到這種問題,我是嘗試去作循環利用的,可是因爲這裏問題的特殊性(爲何特殊?),我至今仍在思考合適的方法可以達成循環利用的效果。爲了解除這部分同窗的疑問,你可使用如下網易雲音樂,他們是這種模式的締造者,同時經過Reveal觀察,沒有跡象代表他們實現了這部分的循環利用,這就是我對性能問題的交代。若是有一天我找到了一個合適的方式來作循環利用我確定還會寫一篇文章來講明這個過程的。
As we all know,Apple 提供的導航條是用來管理窗口控制器的結構的,某個 UINavigationController
執行 Push
操做後,該導航控制器管理的 controllers
共用一個導航條,若是對該導航條進行自定義,那麼各個界面的導航條都會變成自定義之後的樣式。可是,實際開發中,咱們可能須要爲不一樣的控制器定製不一樣的導航條,就像我 demo 裏寫的同樣.
UITabBarController
做爲根控制器管理着一個導航控制器和一個 UIViewController
UITableViewController
,爲了完整的顯示圖片,該 UITableViewController
的導航欄要求是透明的用 Reveal 觀察了幾個經常使用 App,發現了這種效果的實現大體分3種:
第一種是使用自定義 navigationBar
.淘寶,網易新聞,達令等使用的是這種. 第二種是用截圖的辦法,在 push
到下一個頁面時,截取屏幕,在使用 edgePan
來 pop
時看到的就是背後的截圖,也能實現這種效果.京東,天貓等使用的是這種. 第三種是使用了一種比較特別,比較巧妙的辦法實現的,也就是網易雲音樂的實現方法,後面會分析一下這種實現.
做者用 Reveal 工具考察了實現這一效果的三種已知的方式,在對比這三個實現方式各自的優缺點之後,採用了第三種方式來實現。
要探究實現,先要講清楚一個原則:
UINavigationControler
嵌套 UINavigationControler
的方式是不被容許的,也不能執行壓入棧 push
和出棧 pop
動做跟我看三張圖:
還記得開頭的 demo 嗎?demo 的結構就是這樣一個窗口結構圖:
TabBarController
(上圖紫色的 view
)TabBarController
每個分支子控制器,用一個根導航控制器做爲管理者(上圖小一點的黑色 View
)setNavigationBarHidden:
將根導航控制器的導航欄完全移除rootViewController
和 push
入棧的時候,要先將傳進來的控制器(上圖藍色的 View
)先包裝一層導航控制器(上圖白色的View
)UINavigationControler
嵌套 UINavigationControler
的方式是不被容許的,也不能執行壓入棧 push
和出棧 pop
動做View
)外層再包裝一層 UIViewController
Controller
就擁有了一個本身專有的導航控制器,咱們能夠在對應的控制器的 .m
文件裏對該導航控制器作任何自定義(設置透明度和顏色以及漸變)上面兩張圖,咱們分析了怎麼設定根視圖的結構,以及怎麼包裝用戶傳進來的控制器。 有了以上的基礎之後,咱們就能夠進行入棧和出棧的操做了。 注意:
TabBarController
每個分支子控制器的 push
和 pop
操做都是由根導航控制器負責pop
和 push
操做的對象都是咱們包裝事後的 WarpViewController
,這樣就不會有導航控制器 push
和 pop
導航控制器的衝突了代碼實現見 GitHub。或者也能夠參見原做者的 Github地址。我只是在原做的基礎上加了註釋,並無修改代碼。 若是你對demo中圖片在tableView滾動時的視差效果感興趣,能夠參見我之前的文章 仿Airbnb的tableView頭部視圖層疊效果。 最後,謝謝Github開源做者: JNTian,大寫的感謝。
2016.08.02: 有朋友在QQ上聯繫我說,他在實際開發中有須要在某個界面暫時關閉右滑手勢的需求。因此,加入暫時關閉右滑手勢開關,方便在某些狀況下須要暫時關閉手勢。具體更新見個人GitHub_Demo。
2016.08.04: 上個版本使用類工廠方法,在類工廠方法裏操做了用戶傳進來的控制器的View,因此會形成在應用啓動的時候TabBarVC的子控制器一塊兒加載,有性能問題.此次提交修復了這個問題, TabBarVC的子控制器都能遵循懶加載的原則.謝謝:袁小榮同窗(Github)的提醒.
2016.08.08: 這個框架有了較大的更新。具體包括給現有的Pop手勢添加暫時關閉開關,以及自定義響應手勢範圍。在現有基礎上,框架添加了底部聯動視圖,具體實現以及思路,請前往個人文章:1行代碼爲每一個Controller自定義「TabBar」。
2016.09.13 添加了直接拿到根導航控制器的接口,方便使用popToViewController功能。具體見demo第三個控制器的Pop。
注意: tabBar 的 translucent 默認爲 YES, 使用 JPNavigationCotroller 不能修改 tabBar 的透明屬性. 這是由於 Xcode 9 之後, 蘋果對導航控制器內部作了一些修改, 一旦將 tabBar 設爲不透明, 當前架構下的 UI 就會錯亂, 設置 tabBar 的 backgroundImage 爲不透明圖片, 或者設置 backgroundColor 爲不透明的顏色值也是同樣的會出錯.