iOS之手势滑动返回功能-b
iOS中如果不自定义UINavigationBar,通过手势向右滑是可以实现返回的,这时左边的标题文字提示的是上一个ViewController的标题,如果需要把文字改为简约风格,例如弄过箭头返回啥的,那么你需要自定义UINavigationBar,但当你自定义navigationBar后,这个功能就会自动失效。
屏蔽右滑返回功能代码:
- if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
- self.navigationController.interactivePopGestureRecognizer.enabled = NO;
- }
开启滑动返回功能代码:
- - (void)viewWillAppear:(BOOL)animated{
- [super viewWillAppear:animated];
- // 右滑返回
- if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
- self.navigationController.interactivePopGestureRecognizer.delegate = nil;
- }
- }
注意各种坑:
"在一级视图中,iOS样式返回的手势滑动一下,然后进入二级视图,发现画面卡住了,按Home键转入后台,再返回应用,发现并没有Crash掉,而是直接跳到了二级视图里,运行正常了,大家知道push和pop的原理是用进栈出栈完成的,可能因为在一级视图中滑动那一下,影响了视图在栈中的位置。 "
------有人提到通过以下方法处理:“一级视图中一定要加入self.navigationController.interactivePopGestureRecognizer.enabled = NO;,先把iOS7手势返回屏蔽掉,到二级视图再用self.navigationController.interactivePopGestureRecognizer.enabled = YES打开”
自己写了个demo试运行,发现self.navigationController.interactivePopGestureRecognizer.enabled 不能动态设置更改状态。因此该方法不可行。
解决方法:
- - (void)viewDidAppear:(BOOL)animated
- {
- __weak typeof(self) weakSelf = self;
- self.navigationController.interactivePopGestureRecognizer.delegate = weakSelf;
- }
实现手势协议:
- #pragma mark - UIGestureRecognizerDelegate
- - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer*)gestureRecognizer{
- //判断是否为rootViewController
- if (self.navigationController && self.navigationController.viewControllers.count == 1) {
- return NO;
- }
- return YES;
- }
但问题又来了,如果是一个显示成功/失败结果页,滑动返回不大符合正常思维,因为需要选择性屏蔽处理。
终极解决方法:自定义全屏滑动手势UIPanGestureRecognizer
- //
- // BasicNavigationController.m
- //
- //
- // Copyright (c) 2016年 lvxiangan520@126.com. All rights reserved.
- //
- #import "BasicNavigationController.h"
- #import "BaseResultViewController.h"
- @interface BasicNavigationController() <UIGestureRecognizerDelegate>
- @end
- @implementation BasicNavigationController
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- [self.navigationBar setTitleTextAttributes:@{NSForegroundColorAttributeName : WhiteColor}];
- // 获取系统自带滑动手势的target对象
- id target = self.interactivePopGestureRecognizer.delegate;
- // 创建全屏滑动手势,调用系统自带滑动手势的target的action方法
- UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:target action:@selector(handleNavigationTransition:)];
- // 设置手势代理,拦截手势触发
- pan.delegate = self;
- // 给导航控制器的view添加全屏滑动手势
- [self.view addGestureRecognizer:pan];
- // 禁止使用系统自带的滑动手势
- self.interactivePopGestureRecognizer.enabled = NO;
- }
- - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
- {
- [viewController.navigationItem.backBarButtonItem setTitleTextAttributes:@{NSFontAttributeName : [UIFont systemFontOfSize:Scale_Size_Smaller()]} forState:UIControlStateNormal];
- if (self.childViewControllers.count > 0) {
- viewController.hidesBottomBarWhenPushed = YES;
- }
- [super pushViewController:viewController animated:YES];
- }
- - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
- {
- // 注意:只有非根控制器才有滑动返回功能,根控制器没有。
- // 判断导航控制器是否只有一个子控制器,如果只有一个子控制器,肯定是根控制器
- if (self.childViewControllers.count == 1) {
- // 表示用户在根控制器界面,就不需要触发滑动手势,
- return NO;
- }
- // 当前页面是显示结果页,不响应滑动手势
- UIViewController *vc = [self.childViewControllers lastObject];
- if ([vc isKindOfClass:[BaseResultViewController class]]) {
- return NO;
- }
- return YES;
- }
- @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界面。
推荐大家个朋友开的淘宝小店店, 欢迎光临
iOS之手势滑动返回功能-b的更多相关文章
- iOS之手势滑动返回功能
iOS中如果不自定义UINavigationBar,通过手势向右滑是可以实现返回的,这时左边的标题文字提示的是上一个ViewController的标题,如果需要把文字改为简约风格,例如弄过箭头返回啥的 ...
- 再谈iOS 7的手势滑动返回功能
本文转载至 http://blog.csdn.net/jasonblog/article/details/28282147 之前随手写过一篇<使用UIScreenEdgePanGestureR ...
- 禁用ios7 手势滑动返回功能
禁用ios7 手势滑动返回功能 版权声明:本文为博主原创文章,未经博主允许不得转载. 在有的时候,我们不需要手势返回功能,那么可以在页面中添加以下代码: - (void)viewDidAppear:( ...
- ios 侧边手势滑动返回 禁用/开启 功能
// 禁用 返回手势 if ([self.navigationController respondsToSelector:@selector(interactivePopGestureR ...
- iOS 7的手势滑动返回
如今使用默认模板创建的iOS App都支持手势返回功能,假设导航栏的返回button是自己定义的那么则会失效,也能够參考这里手动设置无效. if ([self.navigationController ...
- iOS彩票项目--第五天,新特性引导页的封装、返回按钮的自定义、导航控制器的滑动返回以及自定义滑动返回功能
一.上次实现了在AppDelegate中通过判断app版本决定是否进入新特性页面,今天将AppDelegate中的一坨进行了封装.将self.window的根控制器到底应该为新特性界面,还是主页面,封 ...
- UINavigationController实现全屏滑动返回功能
说明: UINavigationController默认在push出的控制器中都有边沿滑动返回功能,但是只能从屏幕左边滑才能返回,若从屏幕中间画并没有效果.下面实现全屏滑动功能. 探究: 系统默认能够 ...
- Android-通过SlidingMenu高仿微信6.2最新版手势滑动返回(二)
转载请标明出处: http://blog.csdn.net/hanhailong726188/article/details/46453627 本文出自:[海龙的博客] 一.概述 在上一篇博文中,博文 ...
- Android-通过SlidingPaneLayout高仿微信6.2最新版手势滑动返回(一)
近期更新了微信版本号到6.2.发现里面有个很好的体验,就是在第二个页面Activity能手势向右滑动返回,在手势滑动的过程中能看到第一个页面,这样的体验很赞,这里高仿了一下. 这里使用的是v4包里面的 ...
随机推荐
- Android内存、性能是程序永恒的话题
内存.性能是程序永恒的话题,实际开发中关于卡顿.OOM也经常是打不完的两只老虎,关于卡顿.OOM的定位方法和工具比较多,这篇文章也不打算赘述了,本章主要是来整理一下JVM的内存模型以及Java对象的生 ...
- poj 3253 Fence Repair(优先队列+哈夫曼树)
题目地址:POJ 3253 哈夫曼树的结构就是一个二叉树,每个父节点都是两个子节点的和. 这个题就是能够从子节点向根节点推. 每次选择两个最小的进行合并.将合并后的值继续加进优先队列中.直至还剩下一个 ...
- dmesg 程序崩溃调试2
dmesg命令基于缓冲区打印信息dmesg -c可以清除该内存信息清除后demsg 命令不显示任何信息,但可以到/var/log/dmesg查看信息 dmesg |tail 20dmesg |head ...
- 进程控制之wait3和wait4函数
大多数UNIX系统实现提供了另外两个函数wait3和wait4.它们提供的功能比POSIX.1函数wait.waitpid和waitid所提供的功能要多一个,这与附加参数rusage有关.该参数要求内 ...
- CopyU!下一次更新将增加对设备厂商及型号的识别!
CopyU!下一版本的更新将加入对设备厂商及型号的识别功能,当用户连接设备时,CopyU!将能够辨别出设备的详细型号等,能够在一定程度上帮助用户发现问题设备或仿冒设备. 敬请期待即将到来的新更新!
- 制作一个类似苹果VFL的格式化语言来描述UIStackView
在项目中总是希望页面上各处的文字,颜色,字体大小甚至各个视图控件布局都能够在发版之后能够修改以弥补一些前期考虑不周,或者根据统计数据能够随时进行调整,当然是各个版本都能够统一变化.看到这样的要求后,第 ...
- HDU1241(bfs)JAVA
import java.util.Scanner;public class Main1241 { public static void main(String[] args) { Scanner ci ...
- C++ notes for beginners(2)
作者:马 岩(Furzoom) (http://www.cnblogs.com/furzoom/)版权声明:本文的版权归作者与博客园共同所有.转载时请在明显地方注明本文的详细链接,未经作者同意请不要删 ...
- Ganymed SSH-2 for Java
Ganymed SSH-2 for Java是一个纯Java实现的SHH2库,官网为http://www.ganymed.ethz.ch/ssh2/,最新的更新时间为2006年10月,在用之前,请仔细 ...
- magento 常用的函数
1.Magento eav_attribute表中source如何指定自定义数据来源 如果你引用的类名为yebihai_usermanage_model_entity_school你必须完整的给出地 ...