仿 Unread 实现位于屏幕底部的优雅导航栏

TL;DR

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

前言

灵感最初来源于 Unread 的 iOS 客户端。

Unread 首页
Unread 首页

当我第一次打开这个应用时,我就被它的 UI 深深吸引了:和大多数国内 app 使用泛滥的 TNV (TabBarController -> NavigationController -> ViewController) 架构不同, Unread 它没有使用 UITabBarController 也没有使用系统自带的 UINavigationController,界面没有任何无关内容,让用户沉浸在应用中,享受应用提供的内容信息流,这种体验简直完美。

它的交互也几乎都是通过手势操作:下拉刷新,右滑(屏幕任何位置)返回,另外左滑和上提同样会触发相应动作。在小屏幕上可能感受不到这种便利,但是在稍微大些的屏幕上如果非要通过点击左上角的返回键才能返回的话,那真的是一件十分痛苦的事情。

Unread 位于底部的导航栏也很有意思,我以为这也是一种很大的创新,它摈弃了系统自带的 navigation bar,将导航栏移到屏幕的最下方,交互同样丝般顺滑,让人赞不绝口。

所以,我就想模仿着实现这样一个导航栏。

思路

当时立马脑海里想到的有三种大致的思路:

第一种,尝试是否能直接更改系统 navigation bar 的位置,将其移至屏幕下方,并设置合理的大小和想要的外形。

第二种,自己实现一个 NavigationController:里面放置一个 UIScrollView,将栈上的 view controller 都放入其中,然后配置一个自定义导航栏,根据 UIScrollView 的 contentOffset 来实现过渡效果。

第三种,直接继承系统的 UINavigationController 并进行私人定制,满足我们的需要。

筛选最优解

针对第一种思路,翻看官方的 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.

因此抛弃思路一。

第二种思路,很明显实现这种思路工作量较大,我们既然有了系统提供的 UINavigationController,为什么不在它提供的接口上进行些许的 tweak ,进而满足我们的需求呢?(其实在 GitHub 上已经有人用第二种方法实现了,有兴趣的读者可以搜搜)

所以最终我选择了短平快的第三种思路:对系统自带导航控制器进行定制,实现需求。

相关知识

关于 UINavigationController:

navigation controller
navigation controller

一个 navigation controller 它自己会维护一个 viewControllers 的数组,另外,navigation controller 有一个属性 view ,该 view 中包含了 navigation bar,toolbar(可选),另外还有一个 content view。在视图的前进以及后退中,只有 content view 是一直在变的(等于 viewControllers 最上面的 view controller 的 view),而 navigation bar 以及 toolbar(可选) 只有内容会变(例如标题),而它们本身作为视图是不变的。

关于 UINavigationItem:

每个被压入 navigation stack 中的 view controller 都必须有 UINavigationItem ,用来展示在 NavigationBar 上面。而 navigation controller 会根据 stack 最上面的两个 view controller 生成 navigation bar 的内容。

关于 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 获取当前需要管理的 UINavigationItem,然后即可获取 UINavigationItem 的 title 等信息,展示在 NavigationBar 上。

如何实现右滑返回时的过渡效果

首先,加上了两个 UILabel: currentTitleLabel 和 priorTitleLabel,分别用来记录当前 view controller 的标题以及前一个 view controller 的标题。
另外,由于 UINavigationController 有一个 UIGestureRecognizer 属性,可以用来追踪右滑的手势,从而可以拿到在当前视图上的偏移量,进而可以实现自定义的过渡效果。
还有,UINavigationBarDelegate 提供了四个代理方法 (shouldPush,didPush,shouldPop,didPop),可以通过这样的四个节点来配置 currentTitleLabel 和 priorTitleLabel 的始末节点时的状态。

目前的效果是这样的:

![](fade in and out)

之后要做的

  • 实现更多的过渡效果
  • 找到更好的解决中途取消右滑返回的方案(现在采用的是一种 work around,具体可以看源代码 TiptoesNavController.swift 中的 handleTiptoesDisplay(sender:) 方法)

个人精力有限,希望可以发挥开源社区的力量吧,最后再贴一下源代码地址:https://github.com/caiyue1993/Tiptoes

如果你单纯喜欢本项目的想法,可以 ⭑Star 支持;如果你对项目代码有更好的建议,可以直接提 issue 或者 pull request。谢谢:)

参考资料

关注我


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

本文版权所有,如需转载,请告知原作者并注明出处

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,233评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,013评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,030评论 0 241
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,827评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,221评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,542评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,814评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,513评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,225评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,497评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,998评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,342评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,986评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,812评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,560评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,461评论 2 266

推荐阅读更多精彩内容