iOS中如果不自定义UINavigationBar,通过手势向右滑是可以实现返回的,这时左边的标题文字提示的是上一个ViewController的标题,如果需要把文字改为简约风格,例如弄过箭头返回啥的,那么你需要自定义UINavigationBar,但当你自定义navigationBar后,这个功能就会自动失效。

屏蔽右滑返回功能代码:

  1. if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
  2. self.navigationController.interactivePopGestureRecognizer.enabled = NO;
  3. }

开启滑动返回功能代码:

  1. - (void)viewWillAppear:(BOOL)animated{
  2. [super viewWillAppear:animated];
  3. // 右滑返回
  4. if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
  5. self.navigationController.interactivePopGestureRecognizer.delegate = nil;
  6. }
  7. }

注意各种坑:

"在一级视图中,iOS样式返回的手势滑动一下,然后进入二级视图,发现画面卡住了,按Home键转入后台,再返回应用,发现并没有Crash掉,而是直接跳到了二级视图里,运行正常了,大家知道push和pop的原理是用进栈出栈完成的,可能因为在一级视图中滑动那一下,影响了视图在栈中的位置。 "

------有人提到通过以下方法处理:“一级视图中一定要加入self.navigationController.interactivePopGestureRecognizer.enabled = NO;,先把iOS7手势返回屏蔽掉,到二级视图再用self.navigationController.interactivePopGestureRecognizer.enabled = YES打开”

自己写了个demo试运行,发现self.navigationController.interactivePopGestureRecognizer.enabled 不能动态设置更改状态。因此该方法不可行。

解决方法:

  1. - (void)viewDidAppear:(BOOL)animated
  2. {
  3. __weak typeof(self) weakSelf = self;
  4. self.navigationController.interactivePopGestureRecognizer.delegate = weakSelf;
  5. }

实现手势协议:

  1. #pragma mark - UIGestureRecognizerDelegate
  2. - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer*)gestureRecognizer{
  3. //判断是否为rootViewController
  4. if (self.navigationController && self.navigationController.viewControllers.count == 1) {
  5. return NO;
  6. }
  7. return YES;
  8. }

但问题又来了,如果是一个显示成功/失败结果页,滑动返回不大符合正常思维,因为需要选择性屏蔽处理。

终极解决方法:自定义全屏滑动手势UIPanGestureRecognizer

    1. //
    2. //  BasicNavigationController.m
    3. //
    4. //
    5. //  Copyright (c) 2016年 lvxiangan520@126.com. All rights reserved.
    6. //
    7. #import "BasicNavigationController.h"
    8. #import "BaseResultViewController.h"
    9. @interface BasicNavigationController() <UIGestureRecognizerDelegate>
    10. @end
    11. @implementation BasicNavigationController
    12. - (void)viewDidLoad
    13. {
    14. [super viewDidLoad];
    15. [self.navigationBar setTitleTextAttributes:@{NSForegroundColorAttributeName : WhiteColor}];
    16. // 获取系统自带滑动手势的target对象
    17. id target = self.interactivePopGestureRecognizer.delegate;
    18. // 创建全屏滑动手势,调用系统自带滑动手势的target的action方法
    19. UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:target action:@selector(handleNavigationTransition:)];
    20. // 设置手势代理,拦截手势触发
    21. pan.delegate = self;
    22. // 给导航控制器的view添加全屏滑动手势
    23. [self.view addGestureRecognizer:pan];
    24. // 禁止使用系统自带的滑动手势
    25. self.interactivePopGestureRecognizer.enabled = NO;
    26. }
    27. - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
    28. {
    29. [viewController.navigationItem.backBarButtonItem setTitleTextAttributes:@{NSFontAttributeName : [UIFont systemFontOfSize:Scale_Size_Smaller()]} forState:UIControlStateNormal];
    30. if (self.childViewControllers.count > 0) {
    31. viewController.hidesBottomBarWhenPushed = YES;
    32. }
    33. [super pushViewController:viewController animated:YES];
    34. }
    35. - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
    36. {
    37. // 注意:只有非根控制器才有滑动返回功能,根控制器没有。
    38. // 判断导航控制器是否只有一个子控制器,如果只有一个子控制器,肯定是根控制器
    39. if (self.childViewControllers.count == 1) {
    40. // 表示用户在根控制器界面,就不需要触发滑动手势,
    41. return NO;
    42. }
    43. // 当前页面是显示结果页,不响应滑动手势
    44. UIViewController *vc = [self.childViewControllers lastObject];
    45. if ([vc isKindOfClass:[BaseResultViewController class]]) {
    46. return NO;
    47. }
    48. return YES;
    49. }
    50. @end

===========================实现app侧滑返回的方案二=================================

在需要开启侧滑返回的viewdidload里面写上    self.navigationController.interactivePopGestureRecognizer.delegate = nil;

或者干脆在  整个app的基类控制器里写上这句。

在每个navi的rootviewcontroller里面写上如下,这两个方法里的东西,是解决在navi根控制器侧滑的时候 出现的视觉bug

- (void)viewDidAppear:(BOOL)animated {

[super viewDidAppear:animated];

if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {

self.navigationController.interactivePopGestureRecognizer.enabled = NO;

}

}

- (void)viewWillDisappear:(BOOL)animated {

[super viewWillDisappear:animated];

if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {

self.navigationController.interactivePopGestureRecognizer.enabled = YES;

}

}

至于,在业务逻辑上不可逆的成功或者失败的结果(比如点击返回要跳转首页,而不是单纯的pop当前页)页侧滑会返回上一页的问题的解决方案如下:

在成功的结果页面,把导航的控制器数组里面的不需要的控制器移除即可。

比如从  a-PUSH-b-PUSH-c-PUSH-d(成功页面, 点击返回和侧滑返回都需要返回到a,不能返回b和c)

NSMutableArray *marr = [[NSMutableArray alloc]initWithArray:self.navigationController.viewControllers];

for (int i=0; i<marr.count-1; i++) {

UIViewController * VC = marr[i];

if ([VC isKindOfClass:[B class]]) {

[marr removeObject:VC];

}

}

for (int i=0; i<marr.count-1; i++) {

UIViewController * VC = marr[i];

if ([VC isKindOfClass:[c class]]) {

[marr removeObject:VC];

}

}

self.navigationController.viewControllers = marr;

大家是通过方案一 还是  方案二 解决的,可以留言告诉我。

=======================================================

扩展:系统自带的向右滑动手势返回上一个界面,ios7--手势

当从控制器A push到控制器B,我们返回控制器A,除了使用按钮返回

[self.navigationController pushViewController:Vc animated:YES];

还可以使用ios7出来的向右滑动,返回控制器A

文档中是这样定义的:

@property(nullable, nonatomic, weak) id<UINavigationControllerDelegate> delegate;

@property(nullable, nonatomic, readonly) UIGestureRecognizer *interactivePopGestureRecognizer NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED;

----------------------------------------------------------------------

我们在控制器B中的viewDidLoad中

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
self.navigationController.interactivePopGestureRecognizer.enabled = YES; // 手势有效设置为YES 无效为NO
self.navigationController.interactivePopGestureRecognizer.delegate = self; // 手势的代理设置为self
}

但是当回到控制器A中时,再想push到控制器B,就会出现卡屏,不会动的现象,因为rootView也会有向右滑动返回的问题

要解决这个问题,我们只需在控制器A的viewDidAppear中设置,interactivePopGestureRecognizer为NO:

-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
self.navigationController.interactivePopGestureRecognizer.enabled = NO;
} }

这样即可以保证再B中向右滑返回A动后再次pushB时不会卡在A界面。

推荐大家个朋友开的淘宝小店店, 欢迎光临

https://shop545764523.taobao.com/

iOS之手势滑动返回功能的更多相关文章

  1. iOS之手势滑动返回功能-b

    iOS中如果不自定义UINavigationBar,通过手势向右滑是可以实现返回的,这时左边的标题文字提示的是上一个ViewController的标题,如果需要把文字改为简约风格,例如弄过箭头返回啥的 ...

  2. 再谈iOS 7的手势滑动返回功能

    本文转载至 http://blog.csdn.net/jasonblog/article/details/28282147  之前随手写过一篇<使用UIScreenEdgePanGestureR ...

  3. 禁用ios7 手势滑动返回功能

    禁用ios7 手势滑动返回功能 版权声明:本文为博主原创文章,未经博主允许不得转载. 在有的时候,我们不需要手势返回功能,那么可以在页面中添加以下代码: - (void)viewDidAppear:( ...

  4. ios 侧边手势滑动返回 禁用/开启 功能

    // 禁用  返回手势       if ([self.navigationController respondsToSelector:@selector(interactivePopGestureR ...

  5. iOS 7的手势滑动返回

    如今使用默认模板创建的iOS App都支持手势返回功能,假设导航栏的返回button是自己定义的那么则会失效,也能够參考这里手动设置无效. if ([self.navigationController ...

  6. iOS彩票项目--第五天,新特性引导页的封装、返回按钮的自定义、导航控制器的滑动返回以及自定义滑动返回功能

    一.上次实现了在AppDelegate中通过判断app版本决定是否进入新特性页面,今天将AppDelegate中的一坨进行了封装.将self.window的根控制器到底应该为新特性界面,还是主页面,封 ...

  7. UINavigationController实现全屏滑动返回功能

    说明: UINavigationController默认在push出的控制器中都有边沿滑动返回功能,但是只能从屏幕左边滑才能返回,若从屏幕中间画并没有效果.下面实现全屏滑动功能. 探究: 系统默认能够 ...

  8. Android-通过SlidingMenu高仿微信6.2最新版手势滑动返回(二)

    转载请标明出处: http://blog.csdn.net/hanhailong726188/article/details/46453627 本文出自:[海龙的博客] 一.概述 在上一篇博文中,博文 ...

  9. Android-通过SlidingPaneLayout高仿微信6.2最新版手势滑动返回(一)

    近期更新了微信版本号到6.2.发现里面有个很好的体验,就是在第二个页面Activity能手势向右滑动返回,在手势滑动的过程中能看到第一个页面,这样的体验很赞,这里高仿了一下. 这里使用的是v4包里面的 ...

随机推荐

  1. hdu 3045 斜率优化DP

    思路:dp[i]=dp[j]+sum[i]-sum[j]-(i-j)*num[j+1]; 然后就是比较斜率. 注意的时这里j+t<=i: #include<iostream> #in ...

  2. 从零开始实现放置游戏(六)——实现挂机战斗(4)导入Excel数值配置

    前面我们已经实现了在后台管理系统中,对配置数据的增删查改.但每次添加只能添加一条数据,实际生产中,大量数据通过手工一条一条添加不太现实.本章我们就实现通过Excel导入配置数据的功能.这里我们还是以地 ...

  3. 美食节(bzoj 2879)

    Description CZ市为了欢迎全国各地的同学,特地举办了一场盛大的美食节.作为一个喜欢尝鲜的美食客,小M自然不愿意错过这场盛宴.他很快就尝遍了美食节所有的美食.然而,尝鲜的欲望是难以满足的.尽 ...

  4. 配置 L3 agent

    上一节我们介绍了路由服务(Routing)的基本功能,今天教大家如何配置. Neutron 的路由服务是由 l3 agent 提供的. 除此之外,l3 agent 通过 iptables 提供 fir ...

  5. VS2008 没办法太强大了

    原文发布时间为:2009-06-13 -- 来源于本人的百度文章 [由搬家工具导入] VS2008 太强大了。。。继续学习。。。。现在微软的某些强大功能也是针对 VS2008了。。。所以。。必须得装上 ...

  6. 《手把手教你学C语言》学习笔记(10)--- 程序的循环控制

    C语言程序设计中,有些代码需要重复执行很多次,循环主要有三类: 一.for循环 1.基本格式为:for(表达式1:表达式2:表达式3){ //表达式1:循环变量赋初值 //表达式2:循环变量满足的条件 ...

  7. Jmeter脚本两种录制方式

    Jmeter 是一个非常流行的性能测试工具,虽然与LoadRunner相比有很多不足,比如:它结果分析能力没有LoadRunner详细:很它的优点也有很多:   l       开源,他是一款开源的免 ...

  8. Algorithm | hash

    A basic requirement is that the function should provide a uniform distribution of hash values. A non ...

  9. 分享Kali Linux 2017.1镜像

     分享Kali Linux 2017.1镜像 Kali Linux官方于4月24日发布Kali Linux 2017.1版本.该版本仍然采用滚动更新方式,所以软件源为kali-rolling.至现在分 ...

  10. Java 8 Lambda表达式的使用

    lambda表达式允许你通过表达式来代替功能接口.lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体(body,可以是一个表达式或一个代码块). Lambda表达式还增 ...