iOS 如何设置导航的滑动返回手势, 和系统饿一样

iOS 7 滑动返回那些事儿

2014/05/17 Wei

.entry-meta

.entry-header

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

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

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

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

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

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

• 良好的交互与动画效果

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

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

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

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

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

Crayon Syntax Highlighter v2.6.4

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

[UINavigationBar appearance].backIndicatorImage = image;

[UINavigationBar appearance].backIndicatorTransitionMaskImage = image;

1

2

3

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

[UINavigationBar appearance].backIndicatorImage = image;

[UINavigationBar appearance].backIndicatorTransitionMaskImage = image;

[Format Time: 0.0036 seconds]

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

Crayon Syntax Highlighter v2.6.4

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

image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];

[UINavigationBar appearance].backIndicatorImage = image;

[UINavigationBar appearance].backIndicatorTransitionMaskImage = image;

1

2

3

4

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

image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];

[UINavigationBar appearance].backIndicatorImage = image;

[UINavigationBar appearance].backIndicatorTransitionMaskImage = image;

[Format Time: 0.0018 seconds]

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

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

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

Crayon Syntax Highlighter v2.6.4

self.navigationController.interactivePopGestureRecognizer.delegate = self;

1

self.navigationController.interactivePopGestureRecognizer.delegate = self;

[Format Time: 0.0007 seconds]

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

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

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

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

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

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

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

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

Crayon Syntax Highlighter v2.6.4

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

{

return YES;

}

1

2

3

4

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

{

return YES;

}

[Format Time: 0.0013 seconds]

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

Crayon Syntax Highlighter v2.6.4

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

{

return [gestureRecognizer isKindOfClass:UIScreenEdgePanGestureRecognizer.class];

}

1

2

3

4

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

{

return [gestureRecognizer isKindOfClass:UIScreenEdgePanGestureRecognizer.class];

}

[Format Time: 0.0014 seconds]

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

4. 其他若干小问题

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

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

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

3 `

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

iOS7-NavigationController-Sample

时间: 2024-11-10 01:02:00

iOS 如何设置导航的滑动返回手势, 和系统饿一样的相关文章

IOS 自定义 滑动返回 手势

/** 只需要在你自定义的导航控制器中,改成如下代码即可,自定义手势返回 */ #define KEY_WINDOW [[UIApplication sharedApplication] keyWindow] #define kScreenW KEY_WINDOW.bounds.size.width #define kAnimateDuration 0.3 #define kDefaultAlapa 0.5 #define kDefaultScale 0.95 #define iOS7 ([UI

一个丝滑的全屏滑动返回手势

一个丝滑的全屏滑动返回手势 全屏返回手势 自 iOS7 之后,Apple 增加了屏幕边缘右划返回交互的支持,再配合上 UINavigationController 的交互式动画,pop 到上一级页面的操作变的非常顺畅和丝滑,从此,我很少再使用点击左上角导航栏上的返回按钮的方式返回了,因为这对单手操作十分不友好:如果一个 App 居然胆敢不支持滑动返回,那离被卸载就不远了. 说到全屏返回手势,首先我感觉这件事本身可能就有问题,毕竟有点反苹果官方的交互,让用户从任意的地方都能够滑 动返回这个交互在国

【转】iOS中设置导航栏标题的字体颜色和大小

原文网址:http://www.360doc.com/content/15/0417/11/20919452_463847404.shtml iOS中设置导航栏标题的字体颜色和大小,有需要的朋友可以参考下. 在平时开发项目的时候,难免会遇到修改导航栏字体大小和颜色的需求,一般使用自定义视图的方法,其实还存在一种方法. 方法一:(自定义视图的方法,一般人也会采用这样的方式) 就是在导航向上添加一个titleView,可以使用一个label,再设置label的背景颜色透明,字体什么的设置就很简单了.

系统级滑动返回手势的屏蔽和开启

屏蔽滑动返回手势 self.navigationController.interactivePopGestureRecognizer.enabled = NO; 重新开启滑动返回手势 self.navigationController.interactivePopGestureRecognizer.enabled = YES;

iOS 一个丝滑的全屏滑动返回手势

原文链接:http://blog.sunnyxx.com/2015/06/07/fullscreen-pop-gesture/ 全屏返回手势 自 iOS7 之后,Apple 增加了屏幕边缘右划返回交互的支持,再配合上 UINavigationController 的交互式动画,pop 到上一级页面的操作变的非常顺畅和丝滑,从此,我很少再使用点击左上角导航栏上的返回按钮的方式返回了,因为这对单手操作十分不友好:如果一个 App 居然胆敢不支持滑动返回,那离被卸载就不远了. 说到全屏返回手势,首先我

关于自定义导航栏,侧滑返回手势消失的问题

连同导航侧滑返回手势消失 self.navigationController.navigationBarHidden = YES; 只消失导航 self.navigationController.navigationBar.hidden = YES; 导航控制器全屏滑动返回效果: 1.导航控制器的view自带了滑动手势,只不过手势的触发范围只能在左边. 2.当用户在界面左边拖动,就会触发滑动手势方法,并且有滑动返回功能,说明系统手势触发的方法已经实现了滑动返回功能. 3.为什么说系统手势触发的方

iOS viewController添加导航条以及返回跳转选择

给单独的viewcontroller或者在Appdelegate的主页面添加导航条,只要在viewcontroller上添加navigationcontroller,在添加此navigationcontroller即可 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow allo

iOS中设置导航栏标题的字体颜色和大小

在平时开发项目的时候,难免会遇到修改导航栏字体大小和颜色的需求,一般使用自定义视图的方法,其实还存在一种方法. 方法一:(自定义视图的方法,一般人也会采用这样的方式) 就是在导航向上添加一个titleView,可以使用一个label,再设置label的背景颜色透明,字体什么的设置就很简单了. //自定义标题视图 UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 200, 44)]; titleLabel.b

iOS 8 设置导航栏的背景颜色和背景图片

如果是storyboard 直接embed一个导航栏,然后在新出现的导航栏 选属性 选一下颜色就可以了 代码实现背景颜色修改:self.navigationController.navigationBar.barTintColor = [UIColor blueColor]; 代码实现背景图片修改:当然在属性里面也是可以添加修改的[self.navigationController.navigationBar setBackgroundImage: [UIImage imageNamed:@"b