iOS 7的手势滑动返回
如今使用默认模板创建的iOS App都支持手势返回功能,假设导航栏的返回button是自己定义的那么则会失效,也能够參考这里手动设置无效。
- if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
- self.navigationController.interactivePopGestureRecognizer.enabled = NO;
- }
假设是由于自己定义导航button而导致手势返回失效,那么能够在NavigationController的viewDidLoad函数中加入例如以下代码:
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- // Do any additional setup after loading the view.
- __weak typeof (self) weakSelf = self;
- if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
- self.interactivePopGestureRecognizer.delegate = weakSelf;
- }
- }
这样写了以后就能够通过手势滑动返回上一层了,可是假设在push过程中触发手势滑动返回。会导致导航栏崩溃(从日志中能够看出)。针对这个问题,我们须要在pop过程禁用手势滑动返回功能:
- - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
- {
- // fix 'nested pop animation can result in corrupted navigation bar'
- if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
- self.interactivePopGestureRecognizer.enabled = NO;
- }
- [super pushViewController:viewController animated:animated];
- }
- - (void)navigationController:(UINavigationController *)navigationController
- didShowViewController:(UIViewController *)viewController
- animated:(BOOL)animated
- {
- if ([navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
- navigationController.interactivePopGestureRecognizer.enabled = YES;
- }
- }
除了使用系统默认的动画,还能够使用自己定义过渡动画(丰满的文档):
- - (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
- animationControllerForOperation:(UINavigationControllerOperation)operation
- fromViewController:(UIViewController *)fromVC
- toViewController:(UIViewController *)toVC
- {
- if (operation == UINavigationControllerOperationPop) {
- if (self.popAnimator == nil) {
- self.popAnimator = [WQPopAnimator new];
- }
- return self.popAnimator;
- }
- return nil;
- }
- - (id<UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController
- interactionControllerForAnimationController:(id<UIViewControllerAnimatedTransitioning>)animationController
- {
- return self.popInteractionController;
- }
- #pragma mark -
- - (void)enablePanToPopForNavigationController:(UINavigationController *)navigationController
- {
- UIScreenEdgePanGestureRecognizer *left2rightSwipe = [[UIScreenEdgePanGestureRecognizer alloc]
- initWithTarget:self
- action:@selector(didPanToPop:)];
- //[left2rightSwipe setDelegate:self];
- [left2rightSwipe setEdges:UIRectEdgeLeft];
- [navigationController.view addGestureRecognizer:left2rightSwipe];
- self.popAnimator = [WQPopAnimator new];
- self.supportPan2Pop = YES;
- }
- - (void)didPanToPop:(UIPanGestureRecognizer *)panGesture
- {
- if (!self.supportPan2Pop) return ;
- UIView *view = self.navigationController.view;
- if (panGesture.state == UIGestureRecognizerStateBegan) {
- self.popInteractionController = [UIPercentDrivenInteractiveTransition new];
- [self.navigationController popViewControllerAnimated:YES];
- } else if (panGesture.state == UIGestureRecognizerStateChanged) {
- CGPoint translation = [panGesture translationInView:view];
- CGFloat d = fabs(translation.x / CGRectGetWidth(view.bounds));
- [self.popInteractionController updateInteractiveTransition:d];
- } else if (panGesture.state == UIGestureRecognizerStateEnded) {
- if ([panGesture velocityInView:view].x > 0) {
- [self.popInteractionController finishInteractiveTransition];
- } else {
- [self.popInteractionController cancelInteractiveTransition];
- }
- self.popInteractionController = nil;
- }
- }
例如以下这个代理方法是用来提供一个非交互式的过渡动画的:
- - (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
- animationControllerForOperation:(UINavigationControllerOperation)operation
- fromViewController:(UIViewController *)fromVC
- toViewController:(UIViewController *)toVC
- {
- if (operation == UINavigationControllerOperationPop) {
- if (self.popAnimator == nil) {
- self.popAnimator = [WQPopAnimator new];
- }
- return self.popAnimator;
- }
- return nil;
- }
而以下这个代理方法则是提供交互式动画:
- - (id<UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController
- interactionControllerForAnimationController:(id<UIViewControllerAnimatedTransitioning>)animationController
- {
- return self.popInteractionController;
- }
这两个组合起来使用。首先。我们须要有个动画:
- @interface WQPopAnimator : NSObject <UIViewControllerAnimatedTransitioning>
- @end
- #import "WQPopAnimator.h"
- @implementation WQPopAnimator
- - (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext
- {
- return 0.4;
- }
- - (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
- {
- UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
- UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
- [[transitionContext containerView] insertSubview:toViewController.view belowSubview:fromViewController.view];
- __block CGRect toRect = toViewController.view.frame;
- CGFloat originX = toRect.origin.x;
- toRect.origin.x -= toRect.size.width / 3;
- toViewController.view.frame = toRect;
- [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
- CGRect fromRect = fromViewController.view.frame;
- fromRect.origin.x += fromRect.size.width;
- fromViewController.view.frame = fromRect;
- toRect.origin.x = originX;
- toViewController.view.frame = toRect;
- } completion:^(BOOL finished) {
- [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
- }];
- }
- @end
其次。交互式动画是通过
- UIPercentDrivenInteractiveTransition
来维护的。在滑动过程中依据滑动距离来进行更新:
- } else if (panGesture.state == UIGestureRecognizerStateChanged) {
- CGPoint translation = [panGesture translationInView:view];
- CGFloat d = fabs(translation.x / CGRectGetWidth(view.bounds));
- [self.popInteractionController updateInteractiveTransition:d];
当手势结束时要做出收尾动作:
- } else if (panGesture.state == UIGestureRecognizerStateEnded) {
- if ([panGesture velocityInView:view].x > 0) {
- [self.popInteractionController finishInteractiveTransition];
- } else {
- [self.popInteractionController cancelInteractiveTransition];
- }
- self.popInteractionController = nil;
- }
相同地。自己定义的动画也会有上面提到的导航栏崩溃问题。也能够通过类似的方法来解决:
- - (void)navigationController:(UINavigationController *)navigationController
- didShowViewController:(UIViewController *)viewController
- animated:(BOOL)animated
- {
- if (viewController == self.navigationController.pushingViewController) {
- self.supportPan2Pop = YES;
- self.navigationController.pushingViewController = nil;
- }
补充:位于当前navgationController的第一个([0])viewController时须要设置手势代理,不响应。
iOS 7的手势滑动返回的更多相关文章
- 再谈iOS 7的手势滑动返回功能
本文转载至 http://blog.csdn.net/jasonblog/article/details/28282147 之前随手写过一篇<使用UIScreenEdgePanGestureR ...
- 禁用ios7 手势滑动返回功能
禁用ios7 手势滑动返回功能 版权声明:本文为博主原创文章,未经博主允许不得转载. 在有的时候,我们不需要手势返回功能,那么可以在页面中添加以下代码: - (void)viewDidAppear:( ...
- Android-通过SlidingMenu高仿微信6.2最新版手势滑动返回(二)
转载请标明出处: http://blog.csdn.net/hanhailong726188/article/details/46453627 本文出自:[海龙的博客] 一.概述 在上一篇博文中,博文 ...
- Android-通过SlidingPaneLayout高仿微信6.2最新版手势滑动返回(一)
近期更新了微信版本号到6.2.发现里面有个很好的体验,就是在第二个页面Activity能手势向右滑动返回,在手势滑动的过程中能看到第一个页面,这样的体验很赞,这里高仿了一下. 这里使用的是v4包里面的 ...
- iOS之手势滑动返回功能-b
iOS中如果不自定义UINavigationBar,通过手势向右滑是可以实现返回的,这时左边的标题文字提示的是上一个ViewController的标题,如果需要把文字改为简约风格,例如弄过箭头返回啥的 ...
- iOS之手势滑动返回功能
iOS中如果不自定义UINavigationBar,通过手势向右滑是可以实现返回的,这时左边的标题文字提示的是上一个ViewController的标题,如果需要把文字改为简约风格,例如弄过箭头返回啥的 ...
- iOS 应用全部添加滑动返回
if ([self class] == [HomeViewController class]||[self class] == [ComprehensivefinanceViewControlle ...
- ios 侧边手势滑动返回 禁用/开启 功能
// 禁用 返回手势 if ([self.navigationController respondsToSelector:@selector(interactivePopGestureR ...
- iOS开发解决页面滑动返回跟scrollView左右划冲突
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithG ...
随机推荐
- Leetcode 385.字典序排序
字典序排序 给定一个整数 n, 返回从 1 到 n 的字典顺序. 例如, 给定 n =1 3,返回 [1,10,11,12,13,2,3,4,5,6,7,8,9] . 请尽可能的优化算法的时间复杂度和 ...
- 84. Spring Boot集成MongoDB【从零开始学Spring Boot】
至于MongoDB网上有很多相关的资料,所以在这里不进行过多的介绍,我们在这里主要是介绍下如何将mongodb与spring boot结合使用.本节大纲: (1) 准备工作: (2) 新建一个mave ...
- java面向抽象编程样例
import java.util.*; abstract class Geometry{ public abstract double getArea(); } class Pillar ...
- iOS学习笔记22-推送通知
一.推送通知 推送通知就是向用户推送一条信息来通知用户某件事件,可以在应用退到后台后,或者关闭后,能够通过推送一条消息通知用户某件事情,比如版本更新等等. 推送通知的常用应用场景: 一些任务管理APP ...
- 【树状数组区间修改单点查询】HDU 4031 Attack
http://acm.hdu.edu.cn/showproblem.php?pid=4031 [题意] 有一个长为n的长城,进行q次操作,d为防护罩的冷却时间,Attack表示区间a-b的墙将在1秒后 ...
- java面试题之什么是ThreadLocal?底层如何实现的?
ThreadLocal是一个解决线程并发问题的一个类,用于创建线程的本地变量,我们知道一个对象的所有线程会共享它的全局变量,所以这些变量不是线程安全的,我们可以使用同步技术.但是当我们不想使用同步的时 ...
- CPU 和内存虚拟化原理
前面我们成功地把 KVM 跑起来了,有了些感性认识,这个对于初学者非常重要.不过还不够,我们多少得了解一些 KVM 的实现机制,这对以后的工作会有帮助. CPU 虚拟化 KVM 的虚拟化是需要 CPU ...
- 【HDOJ5980】Find Small A(签到)
题意:不知道 思路:队友写的 #include <stdio.h> #include <vector> #include <algorithm> #include ...
- 转:关于bugfree的一些不得不说的事
昨天公司说要做一个工作流程控制系统,经朋友建议,尝试使用禅道进行管理,自己试用了下,感觉非常不错.下午看朋友发的关于禅道和bugfree的恩恩怨怨,更加佩服禅道的项目主管. 原文链接:http://w ...
- Delphi中Indy 10的安装和老版本的卸载
http://www.cnblogs.com/railgunman/archive/2010/08/31/1814112.html Indy 10的安装和老版本的卸载 Indy 10下载地址: htt ...