.h:
#import <UIKit/UIKit.h>
@interface UINavigationController (JSFullScreenPopGesture)
/// 自定义全屏拖拽返回手势
@property (nonatomic, strong, readonly) UIPanGestureRecognizer *js_popGestureRecognizer;
@end
.m:
//
// UINavigationController+JSFullScreenPopGesture.m
// test
//
// Created by ShenYj on 16/8/16.
// Copyright © 2016年 ___ShenYJ___. All rights reserved.
//
#import "UINavigationController+JSFullScreenPopGesture.h"
#import <objc/runtime.h>
@interface JSFullScreenPopGestureRecognizerDelegate : NSObject <UIGestureRecognizerDelegate>
@property (nonatomic, weak) UINavigationController *navigationController;
@end
@implementation JSFullScreenPopGestureRecognizerDelegate
- (BOOL)gestureRecognizerShouldBegin:(UIPanGestureRecognizer *)gestureRecognizer {
// 判断是否是根控制器,如果是,取消手势
if (self.navigationController.viewControllers.count <= 1) {
return NO;
}
// 如果正在专场动画,取消手势
if ([[self.navigationController valueForKey:@"_isTransitioning"] boolValue]) {
return NO;
}
// 判断手指移动方向
CGPoint translation = [gestureRecognizer translationInView:gestureRecognizer.view];
if (translation.x <= 0) {
return NO;
}
return YES;
}
@end
@implementation UINavigationController (JSFullScreenPopGesture)
+ (void)load {
Method originalMethod = class_getInstanceMethod([self class], @selector(pushViewController:animated:));
Method swizzledMethod = class_getInstanceMethod([self class], @selector(js_pushViewController:animated:));
method_exchangeImplementations(originalMethod, swizzledMethod);
}
- (void)js_pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
if (![self.interactivePopGestureRecognizer.view.gestureRecognizers containsObject:self.js_popGestureRecognizer]) {
[self.interactivePopGestureRecognizer.view addGestureRecognizer:self.js_popGestureRecognizer];
NSArray *targets = [self.interactivePopGestureRecognizer valueForKey:@"targets"];
id internalTarget = [targets.firstObject valueForKey:@"target"];
SEL internalAction = NSSelectorFromString(@"handleNavigationTransition:");
self.js_popGestureRecognizer.delegate = [self js_fullScreenPopGestureRecognizerDelegate];
[self.js_popGestureRecognizer addTarget:internalTarget action:internalAction];
// 禁用系统的交互手势
self.interactivePopGestureRecognizer.enabled = NO;
}
if (![self.viewControllers containsObject:viewController]) {
[self js_pushViewController:viewController animated:animated];
}
}
- (JSFullScreenPopGestureRecognizerDelegate *)js_fullScreenPopGestureRecognizerDelegate {
JSFullScreenPopGestureRecognizerDelegate *delegate = objc_getAssociatedObject(self, _cmd);
if (!delegate) {
delegate = [[JSFullScreenPopGestureRecognizerDelegate alloc] init];
delegate.navigationController = self;
objc_setAssociatedObject(self, _cmd, delegate, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
return delegate;
}
- (UIPanGestureRecognizer *)js_popGestureRecognizer {
UIPanGestureRecognizer *panGestureRecognizer = objc_getAssociatedObject(self, _cmd);
if (panGestureRecognizer == nil) {
panGestureRecognizer = [[UIPanGestureRecognizer alloc] init];
panGestureRecognizer.maximumNumberOfTouches = 1;
objc_setAssociatedObject(self, _cmd, panGestureRecognizer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
return panGestureRecognizer;
}
@end