仿 Unread 實(shí)現(xiàn)位于屏幕底部的優(yōu)雅導(dǎo)航欄

TL;DR

源代碼 GitHub 地址:https://github.com/caiyue1993/Tiptoes

前言

靈感最初來源于 Unread 的 iOS 客戶端虑绵。

Unread 首頁(yè)
Unread 首頁(yè)

當(dāng)我第一次打開這個(gè)應(yīng)用時(shí)氧腰,我就被它的 UI 深深吸引了:和大多數(shù)國(guó)內(nèi) app 使用泛濫的 TNV (TabBarController -> NavigationController -> ViewController) 架構(gòu)不同买猖, Unread 它沒有使用 UITabBarController 也沒有使用系統(tǒng)自帶的 UINavigationController泻肯,界面沒有任何無關(guān)內(nèi)容海洼,讓用戶沉浸在應(yīng)用中,享受應(yīng)用提供的內(nèi)容信息流休里,這種體驗(yàn)簡(jiǎn)直完美蛆挫。

它的交互也幾乎都是通過手勢(shì)操作:下拉刷新,右滑(屏幕任何位置)返回妙黍,另外左滑和上提同樣會(huì)觸發(fā)相應(yīng)動(dòng)作悴侵。在小屏幕上可能感受不到這種便利,但是在稍微大些的屏幕上如果非要通過點(diǎn)擊左上角的返回鍵才能返回的話拭嫁,那真的是一件十分痛苦的事情可免。

Unread 位于底部的導(dǎo)航欄也很有意思,我以為這也是一種很大的創(chuàng)新做粤,它擯棄了系統(tǒng)自帶的 navigation bar浇借,將導(dǎo)航欄移到屏幕的最下方,交互同樣絲般順滑怕品,讓人贊不絕口妇垢。

所以,我就想模仿著實(shí)現(xiàn)這樣一個(gè)導(dǎo)航欄堵泽。

思路

當(dāng)時(shí)立馬腦海里想到的有三種大致的思路:

第一種,嘗試是否能直接更改系統(tǒng) navigation bar 的位置恢总,將其移至屏幕下方迎罗,并設(shè)置合理的大小和想要的外形。

第二種片仿,自己實(shí)現(xiàn)一個(gè) NavigationController:里面放置一個(gè) UIScrollView纹安,將棧上的 view controller 都放入其中,然后配置一個(gè)自定義導(dǎo)航欄砂豌,根據(jù) UIScrollView 的 contentOffset 來實(shí)現(xiàn)過渡效果厢岂。

第三種,直接繼承系統(tǒng)的 UINavigationController 并進(jìn)行私人定制阳距,滿足我們的需要塔粒。

篩選最優(yōu)解

針對(duì)第一種思路,翻看官方的 UINavigationController 的文檔筐摘,里面寫了這樣一句話:

The navigation controller manages the creation, configuration, and display of the navigation bar and optional navigation toolbar. It is permissible to customize the navigation bar’s appearance-related properties but you must never change its frame, bounds, or alpha values directly.

因此拋棄思路一卒茬。

第二種思路船老,很明顯實(shí)現(xiàn)這種思路工作量較大,我們既然有了系統(tǒng)提供的 UINavigationController圃酵,為什么不在它提供的接口上進(jìn)行些許的 tweak 柳畔,進(jìn)而滿足我們的需求呢?(其實(shí)在 GitHub 上已經(jīng)有人用第二種方法實(shí)現(xiàn)了郭赐,有興趣的讀者可以搜搜)

所以最終我選擇了短平快的第三種思路:對(duì)系統(tǒng)自帶導(dǎo)航控制器進(jìn)行定制薪韩,實(shí)現(xiàn)需求。

相關(guān)知識(shí)

關(guān)于 UINavigationController:

navigation controller
navigation controller

一個(gè) navigation controller 它自己會(huì)維護(hù)一個(gè) viewControllers 的數(shù)組捌锭,另外俘陷,navigation controller 有一個(gè)屬性 view ,該 view 中包含了 navigation bar舀锨,toolbar(可選)岭洲,另外還有一個(gè) content view。在視圖的前進(jìn)以及后退中坎匿,只有 content view 是一直在變的(等于 viewControllers 最上面的 view controller 的 view)盾剩,而 navigation bar 以及 toolbar(可選) 只有內(nèi)容會(huì)變(例如標(biāo)題),而它們本身作為視圖是不變的替蔬。

關(guān)于 UINavigationItem:

每個(gè)被壓入 navigation stack 中的 view controller 都必須有 UINavigationItem 告私,用來展示在 NavigationBar 上面。而 navigation controller 會(huì)根據(jù) stack 最上面的兩個(gè) view controller 生成 navigation bar 的內(nèi)容承桥。

關(guān)于 UINavigationBar, 看官方文檔中的一句話:

A navigation bar is most commonly used within a navigation controller. The UINavigationController object creates, displays, and manages its associated navigation bar, and uses attributes of the view controllers you add to control the content displayed in the navigation bar.

另外驻粟,我們可以通過 UINavigationBarDelegate 獲取當(dāng)前需要管理的 UINavigationItem,然后即可獲取 UINavigationItem 的 title 等信息凶异,展示在 NavigationBar 上蜀撑。

如何實(shí)現(xiàn)右滑返回時(shí)的過渡效果

首先,加上了兩個(gè) UILabel: currentTitleLabel 和 priorTitleLabel剩彬,分別用來記錄當(dāng)前 view controller 的標(biāo)題以及前一個(gè) view controller 的標(biāo)題酷麦。
另外,由于 UINavigationController 有一個(gè) UIGestureRecognizer 屬性喉恋,可以用來追蹤右滑的手勢(shì)沃饶,從而可以拿到在當(dāng)前視圖上的偏移量,進(jìn)而可以實(shí)現(xiàn)自定義的過渡效果轻黑。
還有糊肤,UINavigationBarDelegate 提供了四個(gè)代理方法 (shouldPush,didPush,shouldPop,didPop),可以通過這樣的四個(gè)節(jié)點(diǎn)來配置 currentTitleLabel 和 priorTitleLabel 的始末節(jié)點(diǎn)時(shí)的狀態(tài)氓鄙。

目前的效果是這樣的:

![](fade in and out)

之后要做的

  • 實(shí)現(xiàn)更多的過渡效果
  • 找到更好的解決中途取消右滑返回的方案(現(xiàn)在采用的是一種 work around馆揉,具體可以看源代碼 TiptoesNavController.swift 中的 handleTiptoesDisplay(sender:) 方法)

個(gè)人精力有限,希望可以發(fā)揮開源社區(qū)的力量吧抖拦,最后再貼一下源代碼地址:https://github.com/caiyue1993/Tiptoes把介。

如果你單純喜歡本項(xiàng)目的想法勤讽,可以 ?Star 支持;如果你對(duì)項(xiàng)目代碼有更好的建議拗踢,可以直接提 issue 或者 pull request脚牍。謝謝:)

參考資料

關(guān)注我


本文原地址:http://soledad.me/2017/01/18/about-tiptoes/

本文版權(quán)所有,如需轉(zhuǎn)載巢墅,請(qǐng)告知原作者并注明出處

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末诸狭,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子君纫,更是在濱河造成了極大的恐慌驯遇,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蓄髓,死亡現(xiàn)場(chǎng)離奇詭異叉庐,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)会喝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門陡叠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人肢执,你說我怎么就攤上這事枉阵。” “怎么了预茄?”我有些...
    開封第一講書人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵兴溜,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我耻陕,道長(zhǎng)拙徽,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任诗宣,我火速辦了婚禮膘怕,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘梧田。我一直安慰自己淳蔼,他們只是感情好侧蘸,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開白布裁眯。 她就那樣靜靜地躺著,像睡著了一般讳癌。 火紅的嫁衣襯著肌膚如雪穿稳。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,292評(píng)論 1 301
  • 那天晌坤,我揣著相機(jī)與錄音逢艘,去河邊找鬼旦袋。 笑死,一個(gè)胖子當(dāng)著我的面吹牛它改,可吹牛的內(nèi)容都是我干的疤孕。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼央拖,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼祭阀!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起鲜戒,我...
    開封第一講書人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤专控,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后遏餐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體伦腐,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年失都,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了柏蘑。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡嗅剖,死狀恐怖辩越,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情信粮,我是刑警寧澤黔攒,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站强缘,受9級(jí)特大地震影響督惰,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜旅掂,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一赏胚、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧商虐,春花似錦觉阅、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至叮趴,卻和暖如春割笙,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背眯亦。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工伤溉, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留般码,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓乱顾,卻偏偏與公主長(zhǎng)得像板祝,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子走净,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容