自定义导航控制器实现全屏滑动返回功能

2017-02-19  本文已影响50人  charlotte2018

问题:如果我们在项目中的返回按钮用的是leftBarButtonItem 那么系统自带导航控制器的滑动返回功能失效了。所以用户体验很不好。

1.首先让导航控制器的滑动返回功能恢复。

滑动返回是导航控制器的功能,想到滑动返回,就应该想到手势Gesture.于是我们在导航控制器UINavigationController中去搜索有关手势的关键字Gesture会发现一个属性interactivePopGestureRecognizer。看看官方文档对它的解释吧

QQ20170219-121416@2x.png

翻译一下啊😄这个手势是用来将栈顶控制器移除导航栈的.
导航控制器给它的view添加了这个手势, 用它来将栈顶的控制器移出导航栈.你可以使用这个属性来获取到这个手势对象,也可以将这个手势和你用户界面中的其他手势绑定在一起使用.当你将这些手势混合使用的时候,记得要调用手势的代理方法来允许可以识别多个手势来保证你的手势可以执行它指定的方法.

<UIScreenEdgePanGestureRecognizer: 0x7ff290717eb0; state = Possible; delaysTouchesBegan = YES; 
view = <UILayoutContainerView 0x7ff29051d3e0>; 
target= <(action=handleNavigationTransition:, 
target=<_UINavigationInteractiveTransition 0x7ff290712d00>)>>
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch;

   self.interactivePopGestureRecognizer.delegate = nil;

//
//  MyNavigationController.m
//  OC_test
//
//  Created by wyb on 2017/2/19.
//  Copyright © 2017年 wyb. All rights reserved.
//

#import "MyNavigationController.h"

@interface MyNavigationController ()<UIGestureRecognizerDelegate>

@end

@implementation MyNavigationController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.interactivePopGestureRecognizer.delegate = self;
    
}

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
    
    //如果是根控制器那么就返回no。
    return  self.childViewControllers.count > 1;
    
}


@end

2.如何实现全屏滑动返回功能。

<UIScreenEdgePanGestureRecognizer: 0x7ff290717eb0; state = Possible; delaysTouchesBegan = YES; 
view = <UILayoutContainerView 0x7ff29051d3e0>; 
target= <(action=handleNavigationTransition:, 
target=<_UINavigationInteractiveTransition 0x7ff290712d00>)>>
//
//  MyNavigationController.h
//  OC_test
//
//  Created by wyb on 2017/2/19.
//  Copyright © 2017年 wyb. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface MyNavigationController : UINavigationController

//在项目中有时候咱们的全屏手势会与别的手势发生冲突,这是用来
//控制全屏手势的触发与否的。
@property(nonatomic,assign)BOOL enableBack;

@end
//
//  MyNavigationController.m
//  OC_test
//
//  Created by wyb on 2017/2/19.
//  Copyright © 2017年 wyb. All rights reserved.
//

#import "MyNavigationController.h"

@interface MyNavigationController ()<UIGestureRecognizerDelegate>

@property(nonatomic,strong)UIPanGestureRecognizer *panGesture;

@end

@implementation MyNavigationController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //默认允许全屏手势触发。
    self.enableBack = YES;
    
    //先把系统的返回手势静止了。
    self.interactivePopGestureRecognizer.enabled = NO;
    
    //获取到_UINavigationInteractiveTransition对象。
    id target = self.interactivePopGestureRecognizer.delegate;
    
    //创建panGesture对象,添加添加target对象_UINavigationInteractiveTransition,添加事件handleNavigationTransition:。
    self.panGesture = [[UIPanGestureRecognizer alloc]initWithTarget:target action:@selector(handleNavigationTransition:)];
    
    //把panGesture的代理给导航控制器。
    self.panGesture.delegate = self;
    
    //给导航控制器的view添加全屏手势。
    [self.view addGestureRecognizer:self.panGesture];
    
}

#pragma mark - pan手势的代理方法
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
    //如果是子控制器,而且enableBack = YES,全屏手势才触发。
    if (self.childViewControllers.count>1 && self.enableBack == YES) {
        return YES;
    }
    return  NO;
    
}


@end

上一篇 下一篇

猜你喜欢

热点阅读