iOS 7滑动返回那些事儿

转载 2016年06月01日 11:22:33

在智能机越来越普及,屏幕越做越大的当下,滑动返回手势已经成为了一个应用的标配功能,甚至可以说,不能滑动返回是一种反人类的交互体验。


滑动返回现在大致有以下3种类型:

使用 UISwipeGestureRecognizer 实现,效果为用户在屏幕中向右轻扫手指,页面返回。

使用 UIPanGestureRecognizer 实现,效果为用户在屏幕中向右滑动手指,松开后页面返回。

使用 iOS 7 提供的滑动返回实现,效果为用户手指从屏幕外由左向右进入屏幕,松开后页面返回。

前两种实现方式是 iOS 7 推出之前的普遍做法,现在来看,已经过时且体验不佳,个人推荐使用第三种,优点如下:

良好的交互与动画效果

系统级的支持,实现简单,代码清晰

不会与一些屏幕内的手势产生冲突

虽然优点很明显,但是在使用过程中,还是会有一些值得我们注意的问题,接下来我们就一一解决它们。


1. 如何设置自定义的返回按钮图片?

如果我们的返回按钮不需要显示文字,或者显示的文字是固定的,可以做到图片中去,那么我推荐通过设置 iOS 7 新引入的 backIndicatorImage 来自定义返回按钮。代码如下:

UIImage *image = [UIImage imageNamed:@"nav_back_btn"];

[UINavigationBar appearance].backIndicatorImage = image;

[UINavigationBar appearance].backIndicatorTransitionMaskImage = image;

这样设置后会发现图片被渲染成 navigationBar 的 tintColor 的颜色了,要怎样才能显示出原始的图片颜色呢?还需要用到 iOS 7 中 UIImage 的一个新属性 renderingMode。 我们需要生成一张 renderingMode 为 UIImageRenderingModeAlwaysOriginal 的图片,让我们加上这行代码:

UIImage *image = [UIImage imageNamed:@"nav_back_btn"];

image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];

[UINavigationBar appearance].backIndicatorImage = image;

[UINavigationBar appearance].backIndicatorTransitionMaskImage = image;

这样我们的图片就能显示出原始的颜色了。


2. 使用 UIButton 自定义返回按钮后,如何使用系统的滑动返回?

当我们的返回按钮上需要显示不同的文字时,就不能使用 backIndicatorImage 了,我们要自定义一个 UIButton 来生成 UIBarButtonItem,再设置 navigationBar 的 leftBarButtonItem。而如果设置了 leftBarButtonItem 的话,会使系统的滑动返回失效。我们需要在 UIViewController 中加入这行代码

self.navigationController.interactivePopGestureRecognizer.delegate = self;

运行起来一看,恩…可以滑动返回了。


另外一篇文章中还有一种方法,这种方法需要使用系统的默认文字:

在实际使用中,遇到了一些问题,整理如下:
1、自定义返回按钮后,右滑返回失效;

解决方案:比较直观的办法是在自定义返回按钮时,使用backBarButtonItem:

1     UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
2     //some initialize code here...
3     UIBarButtonItem *barItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
4     self.navigationItem.leftBarButtonItem = barItem;    //not working
5     self.navigationItem.backBarButtonItem = barItem;    //serve well

3. 怎样让滑动返回像默认的效果一样容易触发?

玩了一会儿你发现,好像哪里不对劲,怎么不如之前容易触发了?

没错,当设置了 navigationController.interactivePopGestureRecognizer.delegate 后,虽然滑动返回恢复了,但是它却有点“残疾”,具体表现为两点:

手指滑动的角度必须要几乎水平,而正常的效果可以接受差不多30度的偏差,这在实际使用过程中的体验差别是非常巨大的。

如果 UIViewController 中是一个 UITableView 或者其他可滚动的 UIScrollView,那么在 UIScrollView 滚动的时候,是不能触发滑动返回的,而正常的效果是可以触发的。

那么,我们该怎样解决这两个问题呢?

我们差不多能猜到是因为手势冲突导致的,那我们就先让 ViewController 同时接受多个手势吧。加上代码:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer

{

    return YES;

}

运行试一试,两个问题同时解决,不过又发现了新问题,手指在滑动的时候,被 pop 的 ViewController 中的 UIScrollView 会跟着一起滚动,这个效果看起来就很怪(知乎日报现在就是这样的效果),而且也不是原始的滑动返回应有的效果,那么就让我们继续用代码来解决吧。

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer

{

    return [gestureRecognizer isKindOfClass:UIScreenEdgePanGestureRecognizer.class];

}

加上这段代码后,系统的 UIScreenEdgePanGestureRecognizer 就不会与其他的手势同时触发,从而解决了这个看起来有点奇怪的效果。


4. 其他若干小问题

让我们继续玩儿啊玩儿,还会遇到哪些问题呢?

当在 UINavigationController 的 rootViewController 中做一个会触发滑动返回的操作后,再点击某个会 pushViewController 的按钮时, UINavigationController 没有任何反应,而如果使用 home键 返回主屏,再进入应用的话,会发现已经 push 进刚才应该进入的 ViewController 了,这是因为在 UINavigationController 的 rootViewController 中触发了滑动返回导致的,我们只要判断一下当前 ViewController 是否是 rootViewController,然后在 - gestureRecognizerShouldBegin: 中返回就可以了。

如果我们在 pushViewController 的动画过程中触发滑动返回,会导致闪退,处理方式也很简单,在 push 之后禁用 interactivePopGestureRecognizer, 在 ViewController 显示之后恢复 interactivePopGestureRecognizer 就可以了。我使用了 swizzling 方式在 Category 中统一处理

我将一份 Demo 放到了 Github 上,欢迎大家下载。
iOS7-NavigationController-Sample

iOS 7 滑动返回那些事儿

在智能机越来越普及,屏幕越做越大的当下,滑动返回手势已经成为了一个应用的标配功能,甚至可以说,不能滑动返回是一种反人类的交互体验。 滑动返回现在大致有以下3种类型: 使用 UISwipeG...
  • happyrabbit456
  • happyrabbit456
  • 2014年05月27日 10:26
  • 1082

《明朝那些事儿》心得体会

这本书我看了两遍,并且还正在看第三遍。        因为它实在是太经典了。对于我来说,这些书籍中。文学名著,现代书籍首推《平凡的世界》,仙侠类首推《诛仙》,科幻类推荐《三体》和《小兵传奇》,穿越类首...
  • a1456123a
  • a1456123a
  • 2016年03月10日 11:04
  • 1951

WEB开发那些事儿

web开发由于技术更新快、热点多、新框架层出不穷、贴近最终用户、应用范围广,造成的结果是:它是一个相当令人迷失的领域。写作此文的目的,一方面,是为了寻找一些万变不离其宗的东西,一方面,是对自己在开发过...
  • deltatang
  • deltatang
  • 2014年07月29日 17:55
  • 1876

数据库设计的那些事儿!~(第一篇)

数据库设计的那些事儿!~(第一篇) 各位客官,大家好!今天让我们来聊一聊数据库设计的那些事儿!~ 数据库已经离不开我们的生活,作为一个后端开发人员,数据库的使用更是必不可少的,让我们来看一看为什么...
  • s740556472
  • s740556472
  • 2017年02月15日 21:34
  • 749

Java编程那些事儿系列文章(全集)

Java编程那些事儿1——序言Java编程那些事儿2——程序设计是什么?Java编程那些事儿3——你适合学习程序设计吗?Java编程那些事儿4——如何学好程序设计?Java编程那些事儿5——程序设计介...
  • haifeng314
  • haifeng314
  • 2009年09月23日 12:32
  • 2520

读书笔记:《明朝那些事第三部:妖孽宫廷》

1.“莫须有”杀掉了岳飞,“意欲”杀掉了于谦。2.徐有贞聪明绝顶,认定李贤是他的亲信,可是他错了。石亨位高权重,对李贤许以官位,以为可以拉拢他,可是他也错了。他们都认为这个叫李贤的人会乖乖地听他们的话...
  • ansenamerson
  • ansenamerson
  • 2017年08月25日 12:14
  • 304

编程那些事儿(持续更新中)

现在在用STC12C5A60S2单片机做32*128的LED点阵,各种纠结的问题是遇到不少的。当然,其实大都是一些常识性的错误,但是这些对于初学者而言,如果没有人指导,自己又不喜欢去看书,很难找到错误...
  • fushiqianxun
  • fushiqianxun
  • 2012年04月21日 15:21
  • 659

明朝那些事儿里的王守仁

今天我想跟大家分享的是有关王守仁,也就是王阳明的成长经历。字伯安,别号阳明。我对王守仁了解的不是太多,对他的心学更是还没进行过钻研。所以今天跟大家只是进行一些浅层面的分享。各位同学多多批评指正。一直以...
  • hahawhyha
  • hahawhyha
  • 2016年05月26日 18:31
  • 1770

IP 库的那些事儿之 2013 - 2014 流水帐版

@高春辉 2014 年 11 月 好吧,我先承认我写这篇文章的目的之一是希望各位能重视 IP 库,而不是某个开发人员随便从某些地方就下载一个用然后万年不更新,或者虽然更...
  • charleslei
  • charleslei
  • 2014年11月18日 23:03
  • 2954

HTTPS那些事儿(一)-HTTPS原理

HTTPS那些事儿(一) 最近看了《http权威指南》的几个章节,对HTTPS有了部分了解,同时在网上查阅了一些资料,遂打算记录一下心得,写的仓促,肯定有很多错误的地方,欢迎大家指正。 1.HTTP是...
  • ssjhust123
  • ssjhust123
  • 2014年06月03日 00:37
  • 2134
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:iOS 7滑动返回那些事儿
举报原因:
原因补充:

(最多只允许输入30个字)